java – 如何檢查Hibernate中的實體是否髒?
如何檢查Hibernate中的實體是否處於髒狀態?即我想要只有在某些欄位已更改時,才能設定UpdatedBy和UpdatedAt.所以我可以做物件檢查手動比較2個物件中的每個欄位,但是可能存在一些比較優雅的方式呢?
此外,如果我將物件的欄位設定為與之前相同的值,那麼hibernate會使實體變髒嗎?即:
String name = myEntity.getName() myEntity.setName(name);
編輯:
但是我也有另一個問題 – 我有一個巢狀集合的實體,所以如果只改變了該集合中的元素,那麼我只想在該集合元素上設定UpdatedBy,而不是在擁有該集合的物件上設定.我使用級聯操作進行更新.
是一個很好的問題,這是簡短的答案:Hibernate-Session有一個方法isDirty()
例子的長答案(測試案例1):
如果您在Hibernate之上使用Seam / POJO / JPA.
你可以在呼叫entityManager.flush()之前知道實體是髒的,即知道Hibernate將發出更新語句 – 並在這些記錄上應用一些更改(設定一些值,比如改變記錄等等) .
你知道Hibernate-Session有一個方法isDirty(),但這在某些情況下是不夠的.
你可以在你的persistence.xml檔案中註冊一個Hibernate-Interceptor
<property name="hibernate.ejb.interceptor" value="path.to.MyInterceptor" />
並攔截方法onFlushDirty(…)並將髒物件儲存在地圖中,但如何稍後才能訪問此地圖?我在執行時沒有訪問攔截器(所以我可以呼叫interceptor.getDirtyEntities()),你有這樣的:
public class MyInterceptor extends EmptyInterceptor { private Map<IdentityKey,Object> dirtyEntitiesMap = new HashMap<IdentityKey,Object>(); @Override public boolean onFlushDirty(Object entity, Serializable id, Object[] currentState, Object[] previousState, String[] propertyNames, Type[] types) { dirtyEntitiesMap.put(new IdentityKey(id, entity.getClass()), entity); return super.onFlushDirty(entity, id, currentState, previousState, propertyNames, types); } ... }
解決這個測試案例:
如果您只需要更新,那麼您不需要知道哪些實體更改.您可以在@PreUpdate方法中新增您的程式碼(填充更改它們的使用者).髒的實體將被相應地修改,那些不會得到這個方法被呼叫,因為沒有什麼可以更新(和Hibernate會檢測到).您可以對@PrePersist方法中的新實體執行相同操作,這可能是相同的.您可以使用兩者註釋相同的方法.
如果您還需要記錄哪些欄位已更改,建議先檢視Envers.
http://stackoverflow.com/questions/20393006/how-to-check-if-entity-in-hibernate-is-dirty