如果我有这两个实体:
@Entity class A {
@OneToOne(cascade = CascadeType.MERGE, mappedBy = "a") B b;
//getters+setters
}
@Entity class B {
@OneToOne(cascade = CascadeType.MERGE) A a;
//getters+setters
}
JPA规范是否保证这个?
A a = new A();
B b = new B();
a.setB(b);
b.setA(a);
A managedA = entityManager.merge(a);
// after commit, managedA will have a reference to a managed B which JPA implementation will link to managedA instead of original unmanaged A
Assert.assertTrue(managedA.getB().getA() == managedA);
我的理解是它起作用(至少有时候是最新的EclipseLink),但规范并不保证。
反例/规格摘录欢迎: - )
答案 0 :(得分:1)
你是对的,JPA规范并不保证。事实上,在大多数情况下,merge()的语义是它返回一个新实例 - 由实体管理器创建的托管实例,给定对象的状态合并到其中 - 但这只是一个简化。如果它附加了你放入的对象,那么该方法实际上可以返回void(就像persist()方法那样)。我不知道为什么它的设计是这样的 - 拥有这种不同的语义实际上有点麻烦,我们花了一些时间在我们的应用程序代码中封装了所需的行为。
合并操作的实际语义可以在 3.2.7.1合并JPA规范的分离实体状态最终版本中找到。它的行为会有所不同,具体取决于您放入的对象和当前持久性上下文。
旁注:只要您不使用扩展的持久性上下文,只要事务结束,实体就会变为分离。
另请注意,您通常不应使用==运算符比较对象,因为这实际上不是您对对象比较所需的语义(jvm标识不等于业务对象标识)