@ManyToMany JPA 关系在 join table 和 UK 中使用二度关系
@ManyToMany JPA relation using a 2nd degree relationship in join table and UK
我有这个实体模型(简化版):
@Entity
class A {
@Id
String id;
Collection<B> bs;
}
@Entity
class B {
@Id
String id;
@ManyToOne
@JoinColumn(name = "c_id", nullable = false)
C c;
}
@Entity
class C {
@Id
String id;
}
在 A 和 B(多对多关系)之间添加联接 table 并使用 A.id 和 B.c.id 实施复合 UK 的最佳方法是什么?
我试过这样的事情:
@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"}))
但是我得到一个MultipleBagFetchException
,这很奇怪。这一定与 c_id
不是主键的一部分有关。如果我从 inverseJoinColumns
中删除 c_id
它会按预期工作,但这不是我需要的。
如果 B 和 C 之间是一对一的关联,您可以在这两者之间共享主键,这样
B.id = C.id = B.c.id
那么join table唯一键可以在A.id和B.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 */
}
和一个侦听器来处理 C
的设置:
public class ABListener {
@PrePersist
@PreUpdate
void handleCUpdate(AB ab) {
if (ab.getB() != null) {
ab.setC(ab.getB().getC());
}
}
}
我有这个实体模型(简化版):
@Entity
class A {
@Id
String id;
Collection<B> bs;
}
@Entity
class B {
@Id
String id;
@ManyToOne
@JoinColumn(name = "c_id", nullable = false)
C c;
}
@Entity
class C {
@Id
String id;
}
在 A 和 B(多对多关系)之间添加联接 table 并使用 A.id 和 B.c.id 实施复合 UK 的最佳方法是什么?
我试过这样的事情:
@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"}))
但是我得到一个MultipleBagFetchException
,这很奇怪。这一定与 c_id
不是主键的一部分有关。如果我从 inverseJoinColumns
中删除 c_id
它会按预期工作,但这不是我需要的。
如果 B 和 C 之间是一对一的关联,您可以在这两者之间共享主键,这样
B.id = C.id = B.c.id
那么join table唯一键可以在A.id和B.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 */
}
和一个侦听器来处理 C
的设置:
public class ABListener {
@PrePersist
@PreUpdate
void handleCUpdate(AB ab) {
if (ab.getB() != null) {
ab.setC(ab.getB().getC());
}
}
}