具有复合主键和外键的JPA实体

时间:2016-02-26 17:00:58

标签: java hibernate jpa

我有一个实体,其复合主键由两个字段组成,其中一个字段也是复合外键的一部分。

背景:我有实体PersonAreaSession

PersonAreaSession有多对多的关系,使用名为PersonAreaPersonSession的联接实体。

所以,我有PersonSession,主键为(personIdsessionId)。 PersonIdSessionId本身就是PersonSession的外键。

PersonSession也有一个字段areaId。 我希望(personIdareaId)成为PersonArea的复合外键。

我的PersonSession代码:

@Entity
@Table(name="person_session")
@IdClass(PersonSession.ID.class)
public class PersonSession {

  @Id
  private int personId ;

  @Id
  private int sessionId;

  @ManyToOne
  @JoinColumn(name = "personId", updatable = false, insertable = false, referencedColumnName = "id")
  private Person person;

  @ManyToOne
  @JoinColumn(name = "sessionId", updatable = false, insertable = false, referencedColumnName = "id")
  private Session session;

  @ManyToOne//(cascade = CascadeType.ALL)
  @JoinColumns({
    @JoinColumn(name = "personId", updatable = false, insertable = false),
    @JoinColumn(name = "areaId", updatable = false, insertable = false),
  })
  private PersonArea personArea;

}

PersonSession.Id的代码

public static class ID implements Serializable {
    private int personId;
    private int sessionId;
}

这似乎没问题,它会在数据库中创建所有正确的关系。当我尝试插入PersonSession对象时出现问题 - areaId列始终为null,我认为这是因为它定义了updatable=false, insertable=false

但是,如果我尝试使其可更新和可插入,我会得到一个例外,抱怨personId是一个重复的列:

Caused by: org.hibernate.MappingException: Repeated column in mapping for entity: foo.bar.PersonSession column: personId (should be mapped with insert="false" update="false")

我如何拥有所需的关系并且areaId可以更新和插入?

2 个答案:

答案 0 :(得分:1)

应该能够做到我想要的事情:

@ManyToOne//(cascade = CascadeType.ALL)
@JoinColumns({
  @JoinColumn(name = "personId"),
  @JoinColumn(name = "areaId", updatable = false, insertable = false),
})
private PersonArea personArea;

但是Hibernate不支持混合可更新和不可更新的连接列。接受this question的答案表明它可能会在某个时候得到支持,但似乎开发人员并不十分担心这个缺点。

我对Hibernate如何倾向于支持Eclipselink并且它有效!

答案 1 :(得分:0)

我知道我迟到但我遇到了同样的问题而且我使用了@JoinColumnsOrFormulas来解决它。这是你可以做的:

@JoinColumnsOrFormulas(value = {
        @JoinColumnOrFormula(column = @JoinColumn(name="personId", referencedColumnName = "personId")),
        @JoinColumnOrFormula(formula = @JoinFormula(value="areaId", referencedColumnName = "areaId"))}) 
private PersonArea personArea;