I want to register which changes are made to a certain entity in my app; and I want it to be portable among different implementations of JPA, so I can't use frameworks like Envers (Hibernate) or History Policy (EclipseLink).
So I added a changeLog field to my entity and I'm using an entity listener with the @PreUpdate and @PrePersist annotations to update this field.
The problem is, I'd like to use an annotation to be able to indicate the field in which these changes should be stored, instead of using a fixed name for the field. And when I use reflection to update this field instead of using the set method directly, EclipseLink doesn't seem to be able to detect the change in the changelog field and so, it's not in the generated UPDATE statement
@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);
}
Is this a bug in EclipseLink or is this the expected behavior? Is there a way to mark the changelog field as dirty so that EclipseLink updates its value?