2011-10-10 48 views
1

我試圖運行下面的代碼,但我一直收到錯誤「無法合併已刪除的實體」。無法從實體bean中清除相關實體bean的列表

我的數據庫表如下所示:

banner 
-id 

banner_period 
-id 
-banner_id 
-date 

我的Java代碼:

Banner b = getEntityManager().find(banner.getId()); 
List<BannerPeriod> bps = b.getBannerPeriodList(); 
for (BannerPeriod bp : bps) { 
    getEntityManager().remove(bp); 
} 
// <-- removed code that adds periods here 
b.setBannerPeriodList(bps); 
getEntityManager().merge(b); 

我似乎無法理解這一切的邏輯。任何人都可以解釋它是什麼,我錯過了嗎?我已經嘗試過搜索答案,但是我發現很難定義給出相關結果的關鍵字。

UPDATE:

橫幅實體:

@OneToMany(cascade = CascadeType.ALL, mappedBy = "bannerId") 
private List<BannerPeriod> bannerPeriodList; 

BannerPeriod實體:

@JoinColumn(name = "banner_id", referencedColumnName = "id") 
@ManyToOne(optional = false) 
private Banner bannerId; 
+0

看着橫幅/ BannerPeriod關係將有助於映射定義。你可以發佈他們嗎? –

+0

當然可以。該關係在數據庫中定義爲級聯。請參閱上面的更新。 –

回答

2

List<BannerPeriod> bps仍然包含BannerPeriod S變量。所以當你在b上調用合併時,會發生什麼情況。

merge on b 
-> Cascade all on bannerPeriodList 
-> Iterate over bannerPeriodList and merge them 
**ERROR** The values in bannerPeriodList have been removed. 

試試這個

bps.clear(); 
b.setBannerPeriodList(bps); 
getEntityManager().merge(b); 
+0

謝謝你的建議。我試過了。會發生什麼情況是列表被清除,但合併不會將更改應用到數據庫。這很奇怪,因爲如果我清除列表,確認列表實際上是空的,爲列表添加一個新的BannerPeriod,然後合併,現有的時間段仍然在數據庫中,就像新的一樣。但是當我看着Java中的實體時,只有新添加的BannerPeriod在列表中。這不是因爲關係在數據庫中被破壞了,因爲如果我重新啓動服務器,所有的時期都會回來,無論是舊的還是新的。 –

+1

如果你忽略合併會發生什麼?你還可以在你的ORM中打開SQL調試嗎?這將有助於瞭解幕後發生的情況。 –

+0

謝謝!我從來沒有考慮過這樣做。它在我省略合併時起作用。我發現我必須1)遍歷列表並在每個時期執行getEntityManager()。remove(BannerPeriod),然後2)在句點列表中使用clear(),最後3)省略合併。只有當我將所有這些事情結合起來才能避免異常,並在我的實體和我的數據庫中獲得相同的結果。嗯,我只是在想這一刻...也許我有某種自動提交打開,所以一切提交兩次。我將不得不考慮這一點。 –