问题
I've defined the following class as as default Entity Listener, so every time I call the persist() or merge() methods this code will be executed automatically:
public class StringProcessorListener {
@PrePersist
@PreUpdate
public void formatStrings(Object object) {
try {
for (Field f : object.getClass().getDeclaredFields()) {
if (f.getType().equals(String.class)) {
f.setAccessible(true);
if (f.get(object) != null) {
f.set(object, f.get(object).toString().toUpperCase());
}
}
}
} catch (Exception ex) {
Logger.getLogger(StringProcessorListener.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
The purpose of this is to capitalize all the strings of an object before insert it into the database. The @PrePersist worked fine, the method modifies all the strings and it is saved capitalized on the database, but when I try to update an object it didn't work so well, the method is called normally and it also modifies the strings, but instead of saving the modified object on the database, it is saving the object as it was before this method.
Any ideas on how to solve this?
Update:
I solved it using a DescriptorEvent
, it gave me access to the ObjectChangeSet and I could update it manually, then the values were correctly saved on the database.
回答1:
If running in a server environment or using an agent for weaving, EclipseLink will default to using change tracking where possible for performance reasons. If so, your method of directly setting the values in the object would bypass the woven changetracking code, so EclipseLink isn't aware of the changes. O persist, it uses all values directly from the object, while on updates, it only uses the changed fields, and it would only know about changes through the changetracking listeners. You will either need to use method access to set these fields, or turn off change tracking: http://eclipse.org/eclipselink/documentation/2.5/jpa/extensions/a_changetracking.htm
来源:https://stackoverflow.com/questions/26045966/field-values-are-not-being-modified-on-preupdate-callback