2010-05-31 28 views
0

我被困在使用多字段主鍵的數據庫中。我有一個情況,我有一個主表和詳細信息表,其中詳細信息表的主鍵包含的字段也是外鍵的主表。就像這樣:使用休眠/ JPA批註映射多字段主鍵的問題

Master primary key fields: 
    master_pk_1 

Details primary key fields: 
    master_pk_1 
    details_pk_2 
    details_pk_3 

在主類中,我們定義休眠/ JPA的註釋是這樣的:

@Id 
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "idGenerator") 
@Column(name = "master_pk_1") 
private long masterPk1; 

@OneToMany(cascade=CascadeType.ALL) 
@JoinColumn(name = "master_pk_1", referencedColumnName = "master_pk_1") 
private List<Details> details = new ArrayList<Details>(); 

而且在細節類我已經定義是這樣的ID和回參考:

@EmbeddedId 
@AttributeOverrides({ 
     @AttributeOverride(name = "masterPk1", column = @Column(name = "master_pk_1")), 
     @AttributeOverride(name = "detailsPk2", column = @Column(name = "details_pk_2")), 
     @AttributeOverride(name = "detailsPk2", column = @Column(name = "details_pk_2")) }) 
private DetailsPrimaryKey detailsPrimaryKey = new DetailsPrimaryKey(); 

@ManyToOne 
@JoinColumn(name = "master_pk_1", referencedColumnName = "master_pk_1", insertable=false) 
private Master master; 

所有這些的目標是我可以創建一個新的主人,添加一些細節,當保存時,JPA/Hibernate會在masterPk1字段中爲主人生成新的身份證,並自動通過將其存入細節記錄,將其存儲在DetailsPrimaryKey類中的匹配masterPk1字段中。至少這就是我一直在看的文檔所暗示的。

實際情況是,hibernate似乎正確地創建和更新數據庫中的記錄,但不會將密鑰傳遞給內存中的詳細信息類。相反,我必須自己手動設置它。

我還發現,如果沒有將insertable=true添加到master的後端引用中,那麼hibernate會創建sql,並在insert語句中列出兩次master_pk_1字段,導致數據庫拋出異常。

我的問題是簡單的註釋安排是否正確?還是有更好的方法呢?

回答

2

您可以添加DetailsPrimaryKey映射嗎?

在您的映射中看起來很奇怪的是,您在細節故事中映射了兩次'master_pk_1'列。通過添加insertable = false選項,現在插入工程,但我猜更新仍然不起作用(實際上,當您在實體中多次映射列時,必須使用insertable = false,updatable = false註釋其中的一個)

爲了糾正這一點,我認爲你應該將@ManyToOne Master移動到詳細ID(移除insertable = false選項)。

您還應該將選項mappedBy =「detailsPrimaryKey.master」添加到@OneToMany註釋中,並且如果希望孩子自動保存,也可能是級聯。

(看http://beavercreekconsulting.com/blog/2008/10/hibernate-annotations-for-a-one-to-many-mapping/你會看到非常相似,你的問題代碼解決的東西)

0

我有同樣的問題。起初我想使用@PrimaryKeyJoinColumn,但並不是所有列的Details主鍵都是外鍵。所以我打算使用@JoinColumn。但正如你所說的,JPA實現沒有選擇在寫入數據庫時​​將自動生成的主鍵分配給數據庫,並已諮詢了SEQUENCE表。我認爲這是浪費密鑰,並可能導致併發/同步問題從數據庫中獲取ID甚至可能不會提交給數據庫的實體。