Java @在联接表和UK中使用二次关系的多个JPA关系
我有这个实体模型(简化):Java @在联接表和UK中使用二次关系的多个JPA关系,java,hibernate,jpa,many-to-many,hibernate-mapping,Java,Hibernate,Jpa,Many To Many,Hibernate Mapping,我有这个实体模型(简化): 但是我得到了一个多重回迁异常,这很奇怪。它必须与c_id不是主键的一部分这一事实有关。如果我从inverseJoinColumns中删除c\u id,它会按预期工作,但这不是我所需要的。如果B和c之间是一对一的关联,那么您可以在这两者之间共享主键,以便 B.id = C.id = B.c.id 然后联接表唯一键可以在A.id和B.id之间。我的最终映射如下所示: @ManyToMany(cascade = CascadeType.ALL) @JoinTable
但是我得到了一个
多重回迁异常
,这很奇怪。它必须与c_id
不是主键的一部分这一事实有关。如果我从inverseJoinColumns
中删除c\u id
,它会按预期工作,但这不是我所需要的。如果B和c之间是一对一的关联,那么您可以在这两者之间共享主键,以便
B.id = C.id = B.c.id
然后联接表唯一键可以在A.id和B.id之间。我的最终映射如下所示:
@ManyToMany(cascade = CascadeType.ALL)
@JoinTable
(name = "a_b",
joinColumns = @JoinColumn(name = "a_id"),
inverseJoinColumns = {
@JoinColumn(name = "b_id", referencedColumnName = "id"),
@JoinColumn(name = "c_id", referencedColumnName = "c_id")},
uniqueConstraints = @UniqueConstraint(name = "uk_a_c", columnNames = {"a_id", "c_id"}))
@Entity
@EntityListeners(ABListener.class)
@Table(name = "a_b", uniqueConstraints =
@UniqueConstraint(name = "uk_rel_a_b", columnNames = {"a_id", "c_id"}))
public class AB extends BaseEntity<Long> {
private Long id;
@ManyToOne(optional = false)
@JoinColumn(name = "a_id")
private A a;
@ManyToOne(optional = false)
@JoinColumn(name = "b_id")
private B b;
@ManyToOne(optional = false)
@JoinColumn(name = "c_id")
private C c;
public AB(A a, B b) {
this.a = a;
this.b = b;
}
/* rest of the class */
}
太快了:)谢谢。对不起,我的问题不完整。B和C之间有很多关系。如果是多对一关系,则可以在数据库中使用预插入验证触发器复制B-C关系。无论如何,B已经与A(从A到B有一对多关联)和C(从B到C有多对一关联)关联。因此B已经是a和C的链接表,因此可以在B中添加UK,因为(a.id,C.id)a-B是多对多关系。我曾考虑使用一个包含b.id和b.cúid的JoinTable作为inverseJoinColumns,但由于cúid不是pk的一部分,因此它似乎不起作用(我得到了一个MultipleBagFetchException),如果我们必须急于获取列表或您尝试加入获取两个列表,就会抛出
MultipleBagFetchException
。虽然最终得到的是笛卡尔积,但它也适用于集合。我知道这通常是个问题,但所有的关系都是懒惰的。如果我只在inverseJoinColumns中保留pk,我就不会再收到错误,因此我认为这与inverseJoinColumns中有一个非pk列有关。但我没有找到这方面的任何文件。
@Entity
@EntityListeners(ABListener.class)
@Table(name = "a_b", uniqueConstraints =
@UniqueConstraint(name = "uk_rel_a_b", columnNames = {"a_id", "c_id"}))
public class AB extends BaseEntity<Long> {
private Long id;
@ManyToOne(optional = false)
@JoinColumn(name = "a_id")
private A a;
@ManyToOne(optional = false)
@JoinColumn(name = "b_id")
private B b;
@ManyToOne(optional = false)
@JoinColumn(name = "c_id")
private C c;
public AB(A a, B b) {
this.a = a;
this.b = b;
}
/* rest of the class */
}
public class ABListener {
@PrePersist
@PreUpdate
void handleCUpdate(AB ab) {
if (ab.getB() != null) {
ab.setC(ab.getB().getC());
}
}
}