我有两个连接在一起的对象:
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一样的普通POJO,则为此生成UPDATE
语句。缓存已关闭,我已经验证在调用merge之前对象已正确更新。
答案 0 :(得分:3)
请显示完整的代码和映射。
鉴于您正在使用虚拟访问(正确使用此功能吗?),它可能是某种与虚拟访问相关的更改跟踪问题。问题是否在不使用虚拟访问的情况下发生?
尝试设置,
@ChangeTracking(ChangeTrackingType.DEFERRED)
看看这是否有影响。
您也可以尝试,
@InstantiationCopyPolicy