我有2个对象连接在一起,定义如下:
public class A {
...
@Id
@Column(name = "A_ID")
@SequenceGenerator(...)
@GeneratedValue(...)
public Long getA_ID();
@OneToOne(mappedBy = "a", fetch = FetchType.LAZY, cascade = CascadeType.ALL, targetEntity = B.class)
public B getB();
...
}
@VirtualAccessMethods(get = "getMethod", set = "setMethod")
public class B {
...
@Id
public Long getA_ID();
@MapsId
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL ,targetEntity = A.class)
@JoinColumn(name="A_ID")
public A getA();
getMethod(String name);
setMethod(String name, Object value);
...
}
当我进入B并进入A的
em.merge(A)
的INSERT
时,一切正常。但是,如果我对更新执行相同的操作,它将仅更新A。更新逻辑如下所示:@Transactional
public void update(Object fieldOnANewValue, Object fieldOnBNewField) {
A objA = em.executeQuery(...) //loads objA by primary key
objA.setFieldOnA(fieldOnANewValue);
B objB = objA.getB(); //lazy loads objB
objB.setMethod("FieldOnB", fieldOnBNewValue);
}
如果查看日志,则有一条SQL
UPDATE
语句提交对A所做的更改,但没有提交给B的更改。如果我手动调用em.merge(objB)
,则存在相同的问题。有谁确切地知道EclipseLink是做什么来确定是否生成UPDATE
语句的?特别是关于@VirtualAccessMethods
?但是,我之前设置的@OneToOne映射有所不同,然后em.merge(objB)
可以正常工作,再加上INSERT
可以工作,所以我不确定是否是问题所在。另一方面,如果我还有另一个也连接到A上的对象,但是只是一个像A is这样的普通POJO,则会为此生成UPDATE
语句。缓存已关闭,并且我已验证对象在调用合并之前已正确更新。 最佳答案
请显示完整的代码和映射。
鉴于您正在使用虚拟访问权限(您是否正确使用了它?),这可能是与虚拟访问权限有关的某种变更跟踪问题。在不使用虚拟访问的情况下会发生此问题吗?
尝试设置
@ChangeTracking(ChangeTrackingType.DEFERRED)
看看是否有影响。
您也可以尝试
@InstantiationCopyPolicy