2011-09-27 180 views
2

我有以下的現有DB模式,我想用Java和原生的JPA註解來重新創建(使用Hibernate作爲供應商,所以冬眠具體說明會工作作爲最後的手段),其中:JPA複合鍵@OneToMany

CREATE TABLE users (
    user_id NUMBER NOT NULL      -- pk 
); 

CREATE TABLE userdata_keys (
    userdata_key_id NUMBER NOT NULL,   -- pk 
    key VARCHAR2(128) NOT NULL     
); 

CREATE TABLE users_userdata (
    user_id NUMBER NOT NULL,     -- fk users.user_id 
    userdata_key_id NUMBER NOT NULL,   -- fk userdata_keys.userdata_key_id 
    value VARCHAR2(256)       
); 

我由此產生了以下類和註解:

class User { 
    @Id 
    Long id; 
    @OneToMany 
    Set<Userdata> userdata; 
} 

class UserdataKey { 
    @Id 
    Long id; 
    String key; 
} 

class Userdata { 
    String value; 
    @EmbeddedId 
    UserdataId userdataId; 
} 

@Embeddable 
class UserdataId { 
    User user; 
    UserdataKey userdataKey; 
} 

我離開了COLUMNNAME屬性和這裏的實體的其他屬性。
然而,它並不像預期的那樣工作。 如果我沒有指定一個mappedBy屬性爲user.userdata,hibernate會自動創建一個表USERS_USERS_USERDATA,但據我所見不會使用它。但它確實使用我爲用戶數據類指定的表。

因爲我對Java和hibernate還不太熟悉,所以我現在要做的測試是查看hibernate在持久化幾個樣本條目時創建的數據庫模式。

因此,我完全不知道我是否正確地做到了這一點。我閱讀了hibernate文檔和相當多的Google結果,但他們都沒有處理我想要做的事情(組合鍵與「子類」以及它們自己的主鍵)。

+0

有一個類似的問題:http://stackoverflow.com/questions/31600142/how-to-define-onetomany-in-parent-entity-when-child-has-composite-pk – amphibient

回答

3

mappedBy屬性在每個雙向關聯的一側是必需的。當關聯是一對多時,mappedBy屬性放置在單側(即在您的案例的Useruserdata字段中)。

這是因爲當一個關聯是雙向的時,關聯的一邊總是與另一邊相反,因此不需要告訴Hibernate兩次關聯如何映射(即使用哪個連接列或連接表) 。

如果您準備重新創建架構,我會做對(並且更容易),並在users_userdata中使用代理自動生成的密鑰,而不是複合型。在應用程序的所有層中,這將更容易處理。

+0

我想我會採取你的建議並添加一個代理主鍵。 我猜自動生成的表是由於協會的「另一面」?不應該冬眠至少警告這一點? 我會用什麼'mappedBy'屬性?使用'userdataId.user'似乎可行,但我期望'userdataId'是正確的(這會產生一個關於具有不同數量的列的主鍵的錯誤)。 – user967058

+0

是的,生成的表是由於關聯的另一側沒有mappedBy屬性。不,它不應該警告:你可能有兩個不同的單向關聯,一個在一個方向,另一個在另一個方向(例如:一個人有很多孩子,一個孩子有一個老師:兩個不同的關係,所以兩個不同的映射)。 –

+0

它現在似乎與代理主鍵一起工作。非常感謝! – user967058