EclipseLink没有检测到@PreUpdate内部反射所做的更新

时间:2014-06-03 12:48:16

标签: java java-ee jpa eclipselink

我想注册对我的应用中的某个实体进行了哪些更改;我希望它可以在JPA的不同实现之间移植,因此我不能使用像Envers(Hibernate)或历史策略(EclipseLink)这样的框架。

所以我在我的实体中添加了changeLog字段,并且我正在使用带有@PreUpdate@PrePersist注释的实体监听器来更新此字段。

问题是,我想使用注释来指示应该存储这些更改的字段,而不是使用字段的固定名称。当我使用反射更新此字段而不是直接使用set方法时,EclipseLink似乎无法检测changelog字段中的更改,因此,它不在生成的UPDATE中声明

@PreUpdate
@PrePersist
public void updateChangeLog(Object auditable) throws IllegalAccessException {
    Field[] fields = auditable.getClass().getDeclaredFields();
    Field changeLogField = null;

    for (Field field : fields) {
        if (field.getAnnotation(ChangeLog.class) != null) {
            field.setAccessible(true);
            changeLogField = field;
        }
    }


    String changeLog = generateChangeLog();


    // This works
    // ((MyEntity)auditable).setChangeLog(changeLog);

    // This doesn't work!
    changeLogField.set(auditable, changeLog);
}

这是EclipseLink中的错误还是预期的行为?有没有办法将changelog字段标记为脏,以便EclipseLink更新其值?

1 个答案:

答案 0 :(得分:1)

由于性能原因,EclipseLink的编织默认使用更改跟踪。这意味着不会选择直接更改字段。您可以使用访问器方法更改值,这些方法将由更改侦听器获取。否则,您必须按照此处所述关闭更改跟踪: http://eclipse.org/eclipselink/documentation/2.5/jpa/extensions/a_changetracking.htm

或关闭编织。