放弃Hibernate Envers中的修订版

时间:2017-05-29 07:38:56

标签: hibernate-envers

我不需要在某些情况下为实体保存修订版,但如何处理这种方式?我想跳过创建修订版,已经审核过的源代码,没有机会。

如果您尝试在自定义EnversPostInsertEventListenerImpl中进行数据库更改,例如,在相同的事务中进行调用(在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);

然后你会得到下一个例外:

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进行最终修改。

1 个答案:

答案 0 :(得分:0)

在文档中,有一个名为Conditional Auditing的部分讨论了这个问题。

基本概念是您需要覆盖Envers注册的Hibernate事件侦听器,以处理使用您自己的自定义实现触发审计。

您的实现基本上需要扩展Envers侦听器并且:

  1. 检查该事件是否适用于您对跳过感兴趣的实体类型。
  2. 检查修改后的状态,看是否只发生了意味着跳过的情况。
  3. 如果您想跳过,请不要委托超级实施。
  4. 如果您使用的是ValidityAuditStrategy而不是DefaultAuditStrategy,我强烈建议您避免对INSERT操作使用条件审核。

    根据我所知道的UPDATE操作使用条件审计会起作用,但是对原始插入执行此操作将导致永远不会添加ADD行,因此{{1在您尝试审核该实体行的第一个ValidityAuditStrategy上将断言。

    Hibernate 6的目标是超越用户操纵事件监听器进行条件审计的需要,并转向更接近JPA事件监听器注释的方法。有关详细信息,请参阅HHH-11326