2014-09-25 55 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