用于一对多关系的JPA/Hibernate映射表

pho*_*360 5 hibernate jpa one-to-many

我只使用JPA注释和hibernate 4.0.1作为JPA实现.

我有一个Assessment有两套的课Comment:

@Entity
@Table(name = "ASSESSMENT")
public class Assessment{

    @OneToMany(fetch = FetchType.EAGER)
    private Set<Comment> auditComments = new HashSet<Comment>();

    @OneToMany(fetch = FetchType.EAGER)
    private Set<Comment> comments = new HashSet<Comment>();
}
Run Code Online (Sandbox Code Playgroud)

(我正在跳过getter,setter,cascade annotations和其他不相关的代码行)

评论:

@Entity
@Table(name = "COMMENT")
public class Comment{

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Column(columnDefinition = "text")
    private String text;
}
Run Code Online (Sandbox Code Playgroud)

现在,因为a Comment没有引用Assessment(这是故意的),我不能使用mappedBy属性,而Hibernate需要在Comment和之间创建一个映射表Assessment.默认情况下,它名为ASSESSMENT_COMMENT.

如果我只有一组Comment中Assessment,将工作完全正常.ASSESSMENT_COMMENT只有两列:

[ASSESSMENT_ID, COMMENT_ID]
Run Code Online (Sandbox Code Playgroud)

这将完美地代表一对多的关系.

现在问题是:

因为我没有一组Comment但只有两组,Hibernate尝试仅使用一个ASSESSMENT_COMMENT表来映射这两组.该表有3列:

[ASSESSMENT_ID, COMMENT_ID, AUDITCOMMENT_ID]
Run Code Online (Sandbox Code Playgroud)

最重要的是,3列被设置为不可为空.

那肯定行不通.例如,如果我在auditComents中只有一个项目而在注释中没有项目,那么hibernate会尝试在COMMENT_ID中插入一行带有null的行,这会产生SQL异常.

问题:

对我来说,它看起来像一个bug.应该有两个映射表,而不是一个.

那么,1)它是Hibernate中的已知错误吗?2)有办法吗?我可以强制Hibernate创建两个映射表,每个映射表一个.请记住,我无法更改Comment类以引用Assessment(业务逻辑要求)

JB *_*zet 8

首先,您可以在注释表中使用两列来指回他们的评估:

@OneToMany(fetch = FetchType.EAGER)
@JoinColumn(name = "audit_commented_assessment_id")
private Set<Comment> auditComments = new HashSet<Comment>();

@OneToMany(fetch = FetchType.EAGER)
@JoinColumn(name = "commented_assessment_id")
private Set<Comment> comments = new HashSet<Comment>();
Run Code Online (Sandbox Code Playgroud)

如果你想要两个连接表,那就这样说:

@OneToMany(fetch = FetchType.EAGER)
@JoinTable(name = "assessment_audit_comment",
           joinColumns = @JoinColumn(name = "assessment_id"),
           inverseJoinColumns = @JoinColumn(name = "comment_id"))
private Set<Comment> auditComments = new HashSet<Comment>();

@OneToMany(fetch = FetchType.EAGER)
@JoinTable(name = "assessment_comment",
           joinColumns = @JoinColumn(name = "assessment_id"),
           inverseJoinColumns = @JoinColumn(name = "comment_id"))
private Set<Comment> comments = new HashSet<Comment>();
Run Code Online (Sandbox Code Playgroud)

当然,这在文档中有解释.

  • @nize:如果关联是双向的,那么你必须将关联的所有者方评论.在评论中,您将有一个字段`commentedAssessment`和一个字段`auditedAssessment`.它们将与`@ ManyToOne`一起映射,并使用如上所述的连接表,但切换了joinColumns和inverseJoinColumns.在评估中,你只需要`@OneToMany(mappedBy ="auditedAssessment")私有Set <Comment> auditComments;`和`@OneToMany(mappedBy ="commentedAssessment")设置<Comment>评论;` (2认同)