我有一个实体,其复合主键由两个字段组成,其中一个字段也是复合外键的一部分。
背景:我有实体Person
,Area
和Session
。
Person
与Area
和Session
有多对多的关系,使用名为PersonArea
和PersonSession
的联接实体。
所以,我有PersonSession
,主键为(personId
,sessionId
)。
PersonId
和SessionId
本身就是Person
和Session
的外键。
PersonSession
也有一个字段areaId
。
我希望(personId
,areaId
)成为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可以更新和插入?
答案 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;