简体   繁体   English

JPA双向@OneToOne和级联合并

[英]JPA bidirectional @OneToOne and cascade merge

If I have those two entities: 如果我有这两个实体:

@Entity class A { 
    @OneToOne(cascade = CascadeType.MERGE, mappedBy = "a") B b; 
    //getters+setters
}
@Entity class B { 
    @OneToOne(cascade = CascadeType.MERGE) A a; 
    //getters+setters
}

Does the JPA specification guarantee this? 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);

My understanding is that it works (at least with latest EclipseLink, at least sometimes), but that the spec doesn't guarantee that. 我的理解是它起作用(至少有时候是最新的EclipseLink),但规范并不能保证这一点。

Counter-examples / spec excerpts welcome :-) 反例/规格摘录欢迎:-)

You are right, the JPA specification does not guarantee that. 你是对的,JPA规范并不保证。 In fact in most cases the semantics for merge() is that it returns a new instance - a managed instance created by the entity manager, into which the state of the given object is merged - but this is just a simplification. 事实上,在大多数情况下,merge()的语义是它返回一个新实例 - 由实体管理器创建的托管实例,给定对象的状态合并到其中 - 但这只是一个简化。 If it attached the very object that you put in then the method could actually return void (like the persist() method does). 如果它附加了你放入的对象,那么该方法实际上可以返回void(就像persist()方法那样)。 I have no clue why it was designed like that - it was actually a bit of a pain in the ass to have this different semantics and it took us some time to encapsulate the desired behavior in our application code. 我不知道为什么它的设计是这样的 - 拥有这种不同的语义实际上有点痛苦,我们花了一些时间在我们的应用程序代码中封装了所需的行为。

The actual semantics of the merge operation can be found in 3.2.7.1 Merging Detached Entity State of the JPA specifications final release. 合并操作的实际语义可以在3.2.7.1合并JPA规范最终版本的分离实体状态中找到。 It does behave differently depending on the object that you put in and on the current persistence context. 它的行为会有所不同,具体取决于您放入的对象和当前持久性上下文。

Side note: An entity does become detached as soon as the transaction is over as long as you don't use an extended persistence context. 附注:只要您不使用扩展的持久性上下文,只要事务结束,实体就会变为分离。

Please also note that you should usually not compare objects using the == operator since this is actually not the semantics you desire for your object comparison (jvm identity is not equal to business object identity) 还请注意,您通常不应使用==运算符比较对象,因为这实际上不是您对对象比较所需的语义(jvm标识不等于业务对象标识)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM