2017-05-29 81 views
0

我不需要在某些情況下爲實體保存修訂版,但是如何處理這種方式?我只想跳過修改的創建,已經查看源代碼,沒有機會。在Hibernate Envers中放棄修訂版

如果妳試圖在定製EnversPostInsertEventListenerImpl DB的改變,例如,作出這樣(在onPostInsert)在同一事務呼叫:

 PersistedProperty property = dao.findClass(PersistedProperty.class, "where propertyTemplate.id = ? and fileEntry.id = ?", 
       propertyTemplate.getId(), f.getId()); 
     String v = convertObject2String(propertyTemplate, value); 
     if (property == null) { 
      property = new PersistedProperty(propertyTemplate, v, f); 
     } else { 
      property.setValue(v); 
     } 
     dao.merge(property); 

然後U將得到一個異常:

java.util.ConcurrentModificationException 
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901) 
at java.util.ArrayList$Itr.next(ArrayList.java:851) 
at java.util.Collections$UnmodifiableCollection$1.next(Collections.java:1042) 
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:587) 
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:463) 
at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:337) 
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:39) 
at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1435) 
at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:491) 
at org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:3201) 
at org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2411) 
at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:467) 
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:146) 
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.access$100(JdbcResourceLocalTransactionCoordinatorImpl.java:38) 
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:220) 
at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:68) 
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:517) 
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:761) 
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:730) 
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:504) 
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:292) 
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96) 
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:673) 

問題是AbstractSaveEventListener(第318行)中ActionQueue的相同實例的深度重複以及內部事務對ActionQueue的最終修改。

回答

0

在本文檔中,有一個叫做Conditional Auditing部分討論這件事。

的基本概念是,你需要重寫Envers登記處理觸發用自己的自定義實現審計Hibernate的事件偵聽器。

具體如何實施基本需要擴展Envers聽衆和:

  1. 檢查事件是實體類型你感興趣的跳躍。
  2. 檢查修改後的狀態以查看是否只有意味着跳過的情況發生。
  3. 如果你想跳過,只是不要委託給超級實現。

如果您使用的是ValidityAuditStrategy代替DefaultAuditStrategy,我會強烈建議您不要使用有條件審覈INSERT操作。

UPDATE操作使用條件的審覈,從我可以告訴的工作,但在原來的刀片這樣做將導致永遠不會被添加ADD行,因此ValidityAuditStrategy將斷言你試圖審覈第一UPDATE爲那個實體行。

Hibernate 6的目標是超越用戶的需求來操縱事件偵聽器進行條件審計,並向更多的JPA事件偵聽器註釋類似的方法移動。有關更多詳細信息,請參閱HHH-11326

+0

作品,謝謝! – Mayras

+0

如何在自定義EnversPostUpdateEventListenerImpl中注入Spring bean?這是hibernate中任何實例的典型問題。 – Mayras

+0

在調用持久層之前,您可以使用您定義的'ThreadLocal'變量,或者您可以公開bean的單例實例並以此方式訪問它。 – Naros

相關問題