2012-02-06 127 views
0

我有以下的模型(忽略不相關的/明顯的代碼,例如getter和setter方法):@OneToMany關係複合鍵

@Entity 
public class Invoice { 
    @Id // sequence generated 
    private Long invoiceId; 

    @OneToMany(fetch = FetchType.EAGER) 
    @JoinColumn(name = "invoiceId", referencedColumnName = "invoiceId") 
    @OrderBy("id.itemNumber") 
    List<Item> items = new ArrayList<Item>(); 
} 


@Entity 
public class Item { 
    @EmbeddedId 
    private ItemPK id; 
} 


@Embeddable 
public class ItemPK { 
    private Long invoiceId; 
    private Long itemNumber; 
} 

無法更改數據庫的結構,因爲它是一個傳統的DB :(

的itemNumber基本上是從零開始的索引。

如果我利用現有的發票,只是刪除現有的項目,在列表中添加2個新項目,試圖更新發票對象我遇到的所有時種種問題:

如果我離開ItemPK空,我得到: org.hibernate.TransientObjectException:對象是一個未保存的瞬態的實例 - 合併

之前保存的瞬態的實例。如果我試圖填補ItemPK的值我自己(發票和索引的id),我得到:org.hibernate.NonUniqueObjectException:具有相同標識符值的不同對象已與會話相關聯(數據庫中已經有一個發票項目,並且它具有發票ID和索引= 0,就像我的新項目列表中的第一個對象)。

如果我試圖離開invoiceId空(在ItemPK對象),我得到:java.sql.BatchUpdateException:ORA-01400:無法將NULL插入

( 「項目」, 「invoiceId」。)

有沒有辦法讓Hibernate/JPA來處理呢? 或者我是否需要完全刪除關聯,將列表定義爲@Transient,並將其填充並保存到我的服務類中?

謝謝。

回答

1

這裏您實際上有一個雙向關聯,因爲Item實體中的invoiceId實際上是發票的外鍵。因此,您應該將該關聯映射爲雙向關聯,並使用註釋。它的javadoc有一個例子。

+0

我有一個類似的問題,並試圖使用這個,但無法得到它的工作:http://stackoverflow.com/questions/31600142/how-to-define-onetomany-in-parent-entity-when-兒童具有複合-PK – amphibient 2015-07-24 16:16:41