我有2个JPA实体,它们之间有双向关系。
@Entity
public class A {
@ManyToOne(cascade={CascadeType.PERSIST, CascadeType.MERGE})
B b;
// ...
}
和
@Entity
public class B {
@OneToMany(mappedBy="b",cascade={CascadeType.PERSIST, CascadeType.MERGE})
Set<A> as = new HashSet<A>();
// ...
}
现在我更新一个分离的A
的某些字段值,这些字段值也与某些Bs
有关系,反之亦然,并通过
public String save(A a) {
A returnedA = em.merge(a);
}
returnedA
现在在更新它们之前具有A的值。
我想那个
FINEST: Merge clone with references A@a7caa3be
FINEST: Register the existing object B@cacf2dfb
FINEST: Register the existing object A@a7caa3be
FINEST: Register the existing object A@3f2584b8
表示B中引用的As
(仍有旧值)负责覆盖新值?
有没有人提示如何防止这种情况发生?
非常感谢任何想法!
提前致谢。
答案 0 :(得分:1)
Dirk,我遇到了类似的问题,解决方案(我可能没有正确地利用API)非常密集。 Eclipselink维护对象的缓存,如果它们没有更新(合并/持久),数据库通常会反映更改,但级联对象不会更新(特别是父级)。
(我已宣布A为加入多个B的记录) 实体:
public class A
{
@OneToMany(cascade = CascadeType.ALL)
Collection b;
}
public class B
{
@ManyToOne(cascade = {CascadeType.MERGE, CascadeType.REFRESH}) //I don't want to cascade a persist operation as that might make another A object)
A a;
}
在上述情况下,解决方法是:
public void saveB(B b) //"Child relationship"
{
A a = b.getA();//do null checks as needed and get a reference to the parent
a.getBs().add(b); //I've had the collection be null
//Persistence here
entityInstance.merge(a); // or persist this will cascade and use b
}
public void saveA(A a)
{
//Persistence
entityInstance.merge(a) // or persist
}
你在这里所做的是从顶部将链接从链接层叠起来。维护很烦人,但确实解决了这个问题。或者你可以通过检查它是否分离和刷新/更换来处理它,但我发现它不那么令人满意并且不适合工作。
如果有人对正确的设置有更好的答案,我会很高兴听到它。现在我已经为我的关系实体采用了这种方法,这对于维护来说肯定很烦人。
祝你好运,我很乐意听到更好的解决方案。