问题得到了部分解决,提出了新的、更具体的问题。我建议跳过旧内容。
上一标题:《jpa 中级联合并重叠对象树》:
我有多个 jpa 实体树。关系 parent<->child 在 java 中是双向的。父母和孩子都有相互参照。数据库端的关系始终是从子到父的,没有可连接的。树木相互重叠。有循环(在树的总和中)。我想合并所有在树根上调用 EntityManager.merge() 的对象。我尝试在父母双方的所有关系上设置 CascadeType.ALL。结果总是如下,无论根要合并的顺序是什么: java.lang.IllegalStateException: org.hibernate.TransientPropertyValueException: Not-null property references a transient value - 在当前操作之前必须保存瞬态实例:com. example.Foo1 -> com.example.Foo2
我应该怎么做才能使它正确?
新问题(更新):
如果使用合并,原因确实是双向 java 关系没有很好地级联(适用于持久化)。因此,我想根据以下情况提出一个新的、更具体的问题:
A类:
@Entity
class A {
@OneToMany(mappedBy = "a", cascade = CascadeType.All)
List<B> bs;
//...
}
B类:
@Entity
class B {
@ManyToOne
A a;
//...
}
执行:
A a = new A();
B b = new B();
a.setBs(Arrays.asList(new B[]{b});
b.setA(a);
//em.persist(a) works as desired.
//Probably because inserts are postponed to the end of transaction.
em.merge(a); //throws exception:
java.lang.IllegalStateException: org.hibernate.TransientPropertyValueException: 非空属性引用了一个瞬态值 - 在当前操作之前必须保存瞬态实例:com.example.B -> com.example.A
如果我理解正确,a
正在合并并进行级联,尝试b
在他自己的合并之前对他的孩子执行合并。但正确的数据库操作顺序是先插入a
再插入b
。
我解决了从级联中退出的问题。但是我们可以在这里进行级联工作吗?对我来说似乎在物理上是可能的。