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

时间:2012-12-14 10:26:07

标签: 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>();
}

(我正在跳过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;
}

现在,因为Comment没有引用回Assessment(这是故意的),我不能使用 mappedBy 属性并且Hibernate需要创建CommentAssessment之间的映射表。默认情况下,它名为ASSESSMENT_COMMENT。

如果我在Comment中只有一组Assessment,那就可以了。 ASSESSMENT_COMMENT只有两列:

[ASSESSMENT_ID, COMMENT_ID]

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

现在出现问题:

因为我没有一组Comment而是两个,所以Hibernate尝试仅使用一个ASSESSMENT_COMMENT表映射这两组。该表有3列:

[ASSESSMENT_ID, COMMENT_ID, AUDITCOMMENT_ID]

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

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

问题:

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

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

1 个答案:

答案 0 :(得分: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>();

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

@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>();

当然在the documentation中解释了这一点。