2014-09-25 59 views
1

我已经定义了以下类的默认实体监听器,所以每次我打电话时坚持()或合并()方法,该代码将自动执行:字段值不被修改的更新前的回调

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

如何在保存或更新之前执行UpperCase(),就像在实体setUser中执行user = user操作一样。大写() – Rika 2014-09-25 19:06:33

+0

我本来可以做到这一点,但是我必须更改我的项目中的很多代码,我有300多个实体,并且需要做太多的工作才能完成。 – 2014-09-25 19:15:20

+0

如果您只是将PreUpdate注释放在那里,保存工作是否正常? – Rika 2014-09-25 19:51:34

回答

1

如果在服务器环境中运行或使用代理进行编织,EclipseLink将默认在可能的情况下使用更改跟踪,以实现性能原因。如果是这样,那么直接设置对象中值的方法将绕过编织的更改跟踪代码,因此EclipseLink不知道这些更改。 O持久化,它直接使用来自对象的所有值,而在更新时,它仅使用更改的字段,并且它只会通过更改跟踪侦听器了解更改。您将需要使用方法访问来设置这些字段,或者关闭更改跟踪: http://eclipse.org/eclipselink/documentation/2.5/jpa/extensions/a_changetracking.htm