我有这样定义的实体链:
@Entity @Table("A")
class A {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
Integer id;
@OneToOne(mappedBy = "a", cascade = [CascadeType.ALL], orphanRemoval = true)
B b;
}
@Repository
interface RepositoryOfA implements JpaRepository<A, Integer> {}
@Entity @Table("B")
class B {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
Integer id;
@OneToOne @JoinColumn(name = "a_id")
A a;
@OneToOne(mappedBy = "b", cascade = [CascadeType.ALL], orphanRemoval = true)
C c;
}
@Embeddable
class CPK implements Serializable {
@Column(name = "b_id")
val bId: Long
}
@Entity @Table("C")
class C implements Serializable {
@EmbeddedId
CPK id;
@Column(name = "data")
String data;
@OneToOne
@MapsId("b_id")
B b;
}
然后我尝试将B类型的实体添加到B类型的现有实体(已定义子项):
A a = repositoryOfA.findById(some_id).orElseThrow(...);
a.b = new B();
b.id = 0;
b.a = a;
b.c = new C();
c.id = new CPK();
c.id.b_id = 0; // ?????
c.b = b;
c.data = "hello";
repositoryOfA.save(a);
然后我得到java.sql.SQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails ('C', CONSTRAINT 'c_id_fk' FOREIGN KEY ('b_id') REFERENCES 'B' ('id') ON DELETE CASCADE ON UPDATE CASCADE)
我了解为什么会发生这种情况,因此我尝试使用无效的b_id
保留实体,该实体等于零。但是直觉告诉我,Hibernate应该有一些注释,以便绕过它,因为我不想手动进行两步保存:
1)用B保存一个A,其中B.c = null
2)用C保存A和B
有没有办法在一次通话中执行此操作?
答案 0 :(得分:0)
问题是@MapsId
的使用不正确。根据文档value
的{{1}}参数应对应于现有实体属性,而不是该列。
与@MapsId
一样,Hibernate不会抱怨@MapsId
指向一个不存在的实体的奇怪事物