Eclipselink合并无法为更改的值生成UPDATE语句

时间:2012-02-08 19:35:42

标签: java jpa orm eclipselink

我有两个连接在一起的对象:

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之前对象已正确更新。

1 个答案:

答案 0 :(得分:3)

请显示完整的代码和映射。

鉴于您正在使用虚拟访问(正确使用此功能吗?),它可能是某种与虚拟访问相关的更改跟踪问题。问题是否在不使用虚拟访问的情况下发生?

尝试设置,

@ChangeTracking(ChangeTrackingType.DEFERRED)

看看这是否有影响。

您也可以尝试,

@InstantiationCopyPolicy