我想注册对我的应用中的某个实体进行了哪些更改;我希望它可以在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更新其值?
答案 0 :(得分:1)
由于性能原因,EclipseLink的编织默认使用更改跟踪。这意味着不会选择直接更改字段。您可以使用访问器方法更改值,这些方法将由更改侦听器获取。否则,您必须按照此处所述关闭更改跟踪: http://eclipse.org/eclipselink/documentation/2.5/jpa/extensions/a_changetracking.htm
或关闭编织。