2016-04-21 118 views
0

好的,我現在有點糾結了。我讀過很多其他相關問題,但這並沒有幫助我解決我的問題。如果有人能幫助我,我會很高興。正確地級聯這個@OneToMany關係(Spring數據JPA)

我使用Spring數據JPA和我有這兩個實體:


Device.class

private String id; 

@OneToMany(mappedBy = "device", cascade = CascadeType.ALL) 
@JsonIgnore 
@RestResource(exported = false) 
private List<Reading> readings; 

Reading.class

@ManyToOne(cascade = {CascadeType.MERGE}) /*This isn't right...*/ 
@JoinColumn(name = "device_id") 
private Device device; 

期望

我只節能讀數,並期望設備被正確級聯(持續或合併的),這取決於它是否已經存在。 (讀數只插入一次,他們是永遠不會更新)

現實

我只能使這項工作部分:當我使用cascade = CascadeType.ALLcascade = CascadeType.PERSIST

我可以保存第一閱讀及其映射的設備。有一次,我插入具有相同的設備的關係的二讀,我得到的線沿線的東西:

Duplicate entry '457129' for key 'PRIMARY' 
('457129' = Reading.Device.id) 

據我瞭解,第二閱讀實體試圖通過插入新行,而不是級聯其設備更新現有的。

我可以通過使用cascade = CascadeType.MERGE來「解決」這個問題。現在,當我使用現有的Device實體保存新的Reading時,該設備會正確更新。 但是現在我不能再級聯一個還不存在的設備!

Column 'device_id' cannot be null 
(Reading.device_id) 

另存

我收到JSON DTO的和由它創建的實體。

僞代碼:

Reading reading = deserialize(jsonReading); 
Device device = deserialize(device); 

reading.setDevice(device); /* Device entity is detached */ 

readingService.save(reading); 

我想這個問題的一部分,可能與我做設置分離實體?

我在做什麼錯?我的身份不好嗎?發生什麼事?我是否需要手動管理這些交易?

謝謝!

回答

0

根據定義,@OneToMany關聯是父關聯,即使是單向關聯或雙向關聯。只有組織的父方纔有意義將其實體狀態轉換爲兒童。 (來源:Hibernate docs)。

根據文檔,我將從device字段中刪除cascade。 Docs還包含用於存儲PhonePerson的代碼示例,您可以嘗試@OneToMany@ManyToOne

當你沒有張貼保存一部分,我想任何代碼,保存之前設置設備reading作爲

reading.setDevice(device); 
readingDao.save(reading); // depends on your implementation 

當堅持reading對象device應被自動保存。

+0

我刪除了''cascade''但沒有幫助。仍然獲得''列'device_id'不能爲空''。我也爲這個問題增加了保存部分,因爲它可能很重要。 – sldk

+0

您是否使用'@ Id'註釋定義了主鍵?此外,如果您正在創建新對象,則保留id值並在更新時使用它們(但在Dao實現中調用'saveOrUpdate'而不是'save') –

+0

是的。 ''@Id @GeneratedValue private int id;''''閱讀''。 ''@私有字符串ID;''在''設備''上。 – sldk