2011-10-18 67 views
0

我目前在學習Hibernate,我偶然發現了這個問題: 我已經定義了3個實體:User,Module,Permission。用戶和模塊都與Permission具有一對多關係,因此Permission的複合ID由idUser和idModule組成。用戶類的屬性是一組權限,並且使用@OneToMany,cascade = CascadeType.ALL等進行適當註釋。Hibernate級聯+複合id的問題

現在,我使用MyEclipse的逆向工程功能生成了類。權限的id被創建爲一個具有idUser和idModule屬性的獨立類。我想我可以創建一個用戶,爲它添加一些新的權限,從而保存用戶級聯操作,權限將被自動保存。除了操作導致異常之外,這是正確的。我運行下面的代碼:

Permission p = new Permission(); 
p.setId(new PermissionId(null, module.getId()); 
user.getPermissions().add(p); 
session.save(user); 

我的問題是,即使正在正確生成SQL(先保存用戶,然後許可),我從其中規定的數據庫驅動程序(火鳥)得到一個錯誤它不能爲idUser插入一個空值,這是真的,但不應該hibernate傳遞新創建的用戶id到第二個查詢?

這個特殊的場景對我來說感覺非常不直觀,因爲我傾向於將一個空ID傳遞給Permission對象,因爲它是新的,我希望它被創建,但另一方面,我必須設置idModule屬性,因爲模塊已經存在,所以我不太瞭解像這樣的操作應該如何工作。

有誰知道我在做什麼錯?謝謝

回答

0

您需要指定一個cascade action讓Hibernate在保存User時附帶一個瞬態(意味着尚未保存)Permission

順便說一下,您可能需要考慮對Permission對象使用不同的ID策略,例如生成的ID值 - 數據庫中permission行的主鍵如何包含空值?

+0

謝謝。但Cascade.ALL並不適用於所有操作? Permission對象不能有空值。問題是我必須將其idUser屬性設置爲null,因爲用戶尚未創建。我認爲一旦用戶對象被持久化,級聯操作會將此值傳遞給Permission對象。就像我說的那樣,該操作會生成兩個查詢(插入用戶,插入權限),只是插入權限的部分無法訪問新創建的用戶標識。 – JayPea

+0

如果您打算生成權限標識,則不應將其設置爲非空值。 Hibernate需要知道它是否應該爲實體生成一個ID - 而且默認的做法是使用ID未使用的空值 - 參見[手冊]的這部分(http:// docs。 jboss.org/hibernate/core/3.6/reference/en-US/html/example-parentchild.html#example-parentchild-update)。請注意,它指的是使用複合ID執行此操作時遇到的困難。最後,我關於使用生成的值(如自動增量)的建議是針對權限ID而不是權限。 –

+0

問題是,在這種情況下,由於id是複合的,id的一部分是新的(用戶id),另一部分不是(模塊id來自已經存在的模塊對象)。所以我必須至少手動設置ID的模塊部分,否則它不會正確鏈接到模塊實體。但是,如果我理解正確,我必須將整個id屬性留空,否則它不會工作? – JayPea