如何在JPA中拥有2个相同类型的集合?
我在JPA中有两个实体:Entry和Comment。 Entry包含两个Comment对象集合。
@Entity public class Entry { ... @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL) @IndexColumn(base = 1, name = "dnr") private List descriptionComments = new ArrayList(); @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL) @IndexColumn(base = 1, name = "pmnr") private List postMortemComments = new ArrayList(); ... }
为了存储这样的对象,JPA + Hibernate创建了“Entry”表,“Comment”表和SINGLE“Entry_Comment”:
create table Entry_Comment (Entry_id integer not null, postMortemComments_id integer not null, pmnr integer not null, descriptionComments_id integer not null, dnr integer not null, primary key (Entry_id, dnr), unique (descriptionComments_id), unique (postMortemComments_id))
存储对象失败,因为descriptionComments_id
和postMortemComments_id
不能同时“not null”。
如何使用JPA + Hibernate存储包含两个相同类型集合的对象?
这是许多Hibernate错误之一(准确地说是HHH-3410 )。
我已经设法通过将@JoinTable
注释添加到@OneToMany
关系来修复它,每个关系都有自己的表名。
在你的情况下,它看起来像这样:
@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL) @JoinTable(name="entity_descriptioncomments") @IndexColumn(base = 1, name = "dnr") private List descriptionComments = new ArrayList (); @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL) @JoinTable(name="entity_postmortemcomments") @IndexColumn(base = 1, name = "pmnr") private List postMortemComments = new ArrayList ();
注意 :您还必须添加@IndexColumn
注释(因为多个EAGER包的其他Hibernate问题: HHH-1718 / EJB-346 )。
要使用DataNucleus ( http://www.datanucleus.org )存储JPA中的2个集合,您可以完全按照自己的意愿执行操作。 您没有@JoinTable
注释,因此应将FK放置在每个集合的Comment
中。 如果你确实在某个地方有@JoinTable
(或等价的XML),那么设置相应连接表的名称(每个集合一个)也会起作用(因此它们有自己的连接表)。 在DataNucleus中也可以在2个集合之间建立共享连接表,但这不是标准JPA,而是供应商扩展。
如何映射到Hibernate我不知道,但是这是JPA所以应该是一致的,因为这是一个规范的点;-)
从数据模型/域模型的角度来看,存在一个当前映射的缺陷:您在Entry和Comment之间通常只有一个@OneToMany关系。 并且Comment实体应该还有一个名为type的属性,它带有2个值:’ description ‘或’ postMortem ‘。
要与您当前的Entry实现实现内联,您可能需要考虑将Comment实体分解为2个不同的实体(可能使用JPAinheritancefunction)并在Entry中使用@JoinTable注释。
如果您只关心订购,那么如何将两个索引列定义配置为具有相同的名称?