2013-03-05 46 views
0

在過去的幾天裏,我一直在抨擊一個令人沮喪的問題。未修改收集/實體的約束違規

我們有大量的hibernate實體,它們都是生成的代碼。這意味着,繼@OneToMany集合(除其他事項外)創建:

@OneToMany(cascade = CascadeType.ALL) 
@JoinTable(name = "tablename") 
private java.util.List<classname> fieldname; 

在我們的應用程序,我們希望能夠複製這一切對於第二個用戶。我們通過閱讀所有這些類和字段並稍後重新創建它們(通過它們的構造函數)來做到這一點。然而,看起來這個集合導致Hibernate將集合標記爲髒。當Hibernate首先嚐試刪除一行然後再次插入時,這會導致在寫入數據庫時​​出現奇怪的約束衝突。

我的問題是這樣的: 爲什麼Hibernate甚至想刪除然後插入那一行?爲什麼它會失敗?

我的猜測是Hibernate試圖重新創建整個集合,因爲由於某種原因Hibernate認爲它被修改了。但是,情況顯然不是這樣。

編輯:我應該指出,閱讀集合後使用HibernateSession#evict似乎解決了這個問題。然而,這感覺很不方便,我更喜歡更有思想的人。

回答

2

如果你的連接表沒有任何主鍵,那麼hibernate總是把它看作是一個新記錄,並嘗試刪除引用記錄並插入新記錄。

但是,如果你的連接表有自己的主鍵,那麼它將插入記錄,如果主鍵有空,如果主鍵值存在,那麼它將更新其他方式它將刪除表中但不在列表中的記錄。

Hibernate需要主鍵來識別新的或舊的記錄,否則它將永遠是新的連接表格的情況下。

+0

當然!我應該意識到這一點。但是它仍然不能解釋爲什麼刪除查詢失敗,或者爲什麼Hibernate將集合標記爲髒。 – rbottel 2013-03-05 09:46:46