我在JPA中有2个实体:Entry和Comment。 Entry包含两个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”表和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
不能同时“不为空”。
如何使用JPA + Hibernate存储包含两个相同类型集合的对象?
答案 0 :(得分:13)
这是许多Hibernate错误之一(准确地说是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>();
注意:您还必须添加@IndexColumn
注释(因为多个EAGER包的其他Hibernate问题:HHH-1718 / EJB-346)。
答案 1 :(得分:4)
要使用 DataNucleus (http://www.datanucleus.org)在JPA中存储2个类似的集合,您可以完全按照自己的意愿执行操作。您没有@JoinTable
注释,因此对于每个集合,FK应放在Comment
中。如果你确实在某处(或等效的XML)有@JoinTable
,那么设置相应连接表的名称(每个集合一个)也可以工作(因此它们有自己的连接表)。在DataNucleus中也可以在2个集合之间建立共享连接表,但这不是标准JPA,而是供应商扩展。
如何映射到Hibernate我不知道,但是这是JPA所以应该保持一致,因为这是规范的要点; - )
答案 2 :(得分:2)
从数据模型/域模型的角度来看当前映射存在一个缺陷:您在 Entry 单个 @OneToMany 关系>和评论。 评论实体应该还有一个名为 type 的属性,它带有2个值:' description '或' postMortem '
要与您当前的 Entry 实体实现内联,您可能需要考虑将 Comment 实体分解为2个不同的实体(可能使用JPA继承功能)并使用< em> @JoinTable 注释条目。
答案 3 :(得分:0)
如果您只关心订购,那么如何将两个索引列定义配置为具有相同的名称?