我已将以下类定义为默认的Entity Listener,因此每次调用persist()或merge()方法时,此代码都将自动执行:
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);
}
}
}
这样做的目的是在将对象插入数据库之前将其全部大写。 @PrePersist工作得很好,该方法修改了所有字符串,并且它大写保存在数据库中,但是当我尝试更新一个对象时,它没有正常工作,该方法被正常调用,它也修改了字符串,但不是将修改后的对象保存在数据库上,而是将对象保存为此方法之前的状态。
关于如何解决这个问题的任何想法?
更新
我使用DescriptorEvent
解决了它,它让我可以访问ObjectChangeSet,我可以手动更新它,然后将值正确保存在数据库中。
答案 0 :(得分:1)
如果在服务器环境中运行或使用代理进行编织,出于性能原因,EclipseLink将默认使用更改跟踪。如果是这样,直接在对象中设置值的方法将绕过编织的更改跟踪代码,因此EclipseLink不知道这些更改。 O持久化,它直接使用来自对象的所有值,而在更新时,它仅使用更改的字段,并且只知道通过更改跟踪侦听器的更改。您需要使用方法访问权限来设置这些字段,或者关闭更改跟踪: http://eclipse.org/eclipselink/documentation/2.5/jpa/extensions/a_changetracking.htm