如何在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_idpostMortemComments_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 )。

要使用DataNucleushttp://www.datanucleus.org )存储JPA中的2个集合,您可以完全按照自己的意愿执行操作。 您没有@JoinTable注释,因此应将FK放置在每个集合的Comment中。 如果你确实在某个地方有@JoinTable (或等价的XML),那么设置相应连接表的名称(每个集合一个)也会起作用(因此它们有自己的连接表)。 在DataNucleus中也可以在2个集合之间建立共享连接表,但这不是标准JPA,而是供应商扩展。

如何映射到Hibernate我不知道,但是这是JPA所以应该是一致的,因为这是一个规范的点;-)

从数据模型/域模型的角度来看,存在一个当前映射的缺陷:您在EntryComment之间通常只有一个@OneToMany关系。 并且Comment实体应该还有一个名为type的属性,它带有2个值:’ description ‘或’ postMortem ‘。

要与您当前的Entry实现实现内联,您可能需要考虑将Comment实体分解为2个不同的实体(可能使用JPAinheritancefunction)并在Entry中使用@JoinTable注释。

如果您只关心订购,那么如何将两个索引列定义配置为具有相同的名称?