@OneToMany关系复合键
问题描述:
我有以下的模型(忽略不相关的/明显的代码,例如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,并将其填充并保存到我的服务类中?
谢谢。
答
这里您实际上有一个双向关联,因为Item实体中的invoiceId实际上是发票的外键。因此,您应该将该关联映射为双向关联,并使用注释。它的javadoc有一个例子。
我有一个类似的问题,并试图使用这个,但无法得到它的工作:http://*.com/questions/31600142/how-to-define-onetomany-in-parent-entity-when-儿童具有复合-PK – amphibient 2015-07-24 16:16:41