如何在JPA中拥有2个相同类型的集合?

2022-09-03 14:12:17

我在JPA中有2个实体:条目和评论。条目包含两个 Comment 对象集合。

@Entity
public class Entry {
    ...

    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    @IndexColumn(base = 1, name = "dnr")
    private List<Comment> descriptionComments = new ArrayList<Comment>();

    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    @IndexColumn(base = 1, name = "pmnr")
    private List<Comment> postMortemComments = new ArrayList<Comment>();

    ...
}

为了存储这样的对象,JPA+Hibernate创建了“Entry”表,“Comment”表和单个“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))

对象的存储失败,因为不能同时“不为 null”。descriptionComments_idpostMortemComments_id

如何使用 JPA+休眠来存储包含两个相同类型集合的对象?


答案 1

这是许多休眠错误之一(确切地说是HHH-3410)。

我设法通过向关系添加注释来修复它,每个关系都有自己的表名。@JoinTable@OneToMany

在你的情况下,它看起来像这样:

@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@JoinTable(name="entity_descriptioncomments")
@IndexColumn(base = 1, name = "dnr")
private List<Comment> descriptionComments = new ArrayList<Comment>();

@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@JoinTable(name="entity_postmortemcomments")
@IndexColumn(base = 1, name = "pmnr")
private List<Comment> postMortemComments = new ArrayList<Comment>();

注意:您还必须添加注释(因为多个 EAGER 包的另一个休眠问题:HHH-1718/EJB-346)。@IndexColumn


答案 2

要使用DataNucleushttp://www.datanucleus.org)在JPA中存储2个这样的集合,您将完全按照自己的方式进行操作。您没有注释,因此应为每个集合放置一个 FK。如果您确实具有某个位置(或XML等效项),则设置各个连接表的名称(每个集合一个)也将起作用(因此它们具有自己的连接表)。在DataNucleus中也可以在2个集合之间拥有共享联接表,但这不是标准的JPA,而是供应商扩展。@JoinTableComment@JoinTable

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