【问题标题】:Implementing Conditional Envers Auditing (Hibernate 4.3.7.Final)实现条件环境审计(Hibernate 4.3.7.Final)
【发布时间】:2015-01-23 20:14:23
【问题描述】:

我想审核我的实体中的所有属性,但前提是某些属性已更改。 按照文档 (here) 中描述的步骤,我创建了自己的 EnversIntegrator 实现:

public class EnversIntegrator extends org.hibernate.envers.event.spi.EnversIntegrator {
private static final Logger log = LoggerFactory.getLogger(EnversIntegrator.class);  
private AuditConfiguration enversConfiguration;
@Override
public void integrate(Configuration configuration, SessionFactoryImplementor sessionFactory, SessionFactoryServiceRegistry serviceRegistry) {
    log.debug(".... integrate");
    final EventListenerRegistry listenerRegistry = serviceRegistry.getService(EventListenerRegistry.class);
    listenerRegistry.addDuplicationStrategy(EnversListenerDuplicationStrategy.INSTANCE);
    enversConfiguration = AuditConfiguration.getFor(configuration, serviceRegistry.getService(ClassLoaderService.class));
    if (enversConfiguration.getEntCfg().hasAuditedEntities()) {
        log.debug(".... Register listeners");
        listenerRegistry.prependListeners(EventType.POST_DELETE, new MyPostDeleteEventListener(enversConfiguration));
        listenerRegistry.prependListeners(EventType.POST_INSERT, new MyPostInsertEnversEventListener(enversConfiguration));
        listenerRegistry.prependListeners(EventType.POST_UPDATE, new  MyPostUpdateEnversEventListener(enversConfiguration));
    }
}
@Override
public void disintegrate(SessionFactoryImplementor sessionFactory, SessionFactoryServiceRegistry serviceRegistry) {
    if (enversConfiguration != null) {
        enversConfiguration.destroy();
    }
}

地点:

MyPostInsertEnversEventListener extends org.hibernate.envers.event.spi.EnversPostInsertEventListenerImpl

 MyPostUpdateEnversEventListener extends org.hibernate.envers.event.spi.EnversPostUpdateEventListenerImpl

重写 onPostUpdate 或 onPostInsert(PostInsertEvent evt) 无效,每次执行测试时,都会在 _AUD 表中添加一条新记录。

public void onPostUpdate(PostUpdateEvent evt) {     
    LOG.debug(" ... onPostUpdate " + evt.getEntity().getClass());
//here is my logic who decide if the super.onPostUpdate(evt) must be call or not  
//But NO  super.onPostUpdate(evt); is called !!!!!

}

更新地址实体展位 onPostUpdate 和 onPostInsert 被调用:

[DEBUG] xxxx.hibernate.MyPostUpdateEnversEventListener -  ... onPostUpdate class xxxxxxx.model.Address
[DEBUG] xxxx.hibernate.MyPostInsertEnversEventListener -  ... onPostInsert class org.hibernate.envers.DefaultRevisionEntity
[DEBUG] xxxx.hibernate.MyPostInsertEnversEventListener -  ... onPostInsert class java.util.HashMap

如何防止在 _aud 表中创建此新记录?

非常感谢!

【问题讨论】:

    标签: hibernate hibernate-envers


    【解决方案1】:

    对于较新的版本,该属性是 hibernate.envers.autoRegisterListeners 而不是 hibernate.listeners.envers.autoRegister
    最后一个只是一个遗产。您可以查看 EnversIntegratorEnversServiceImpl 类。

    对于弹簧靴,您可以设置:

    spring.jpa.properties.hibernate.envers.autoRegisterListeners=false
    

    【讨论】:

      【解决方案2】:

      您需要子类化事件侦听器,例如PostInsertEnversEventListener,在那里进行条件审计检查,如果检查通过则调用super方法。

      【讨论】:

      • PostInsertEnversEventListener(现在是 MyPostInsertEnversEventListener)是我的实现。我没有t call super.onPostInsert(evt) or super.onPostUpdate. Ive 减少我的测试只是为了看看我是否可以控制这个插入。更新我的实体时,Envers 使用我的测试实体调用 onPostUpdate,并使用 org.hibernate.envers.DefaultRevisionEntity 和 java.util.HashMap 调用两次 onPostInsert。显然,另一个听众在 _AUD 中插入了一条新记录,完全忽略了我的代码。如果 Envers 在 jQuery 中有类似 event.preventDefault() 的东西,我会徘徊。
      【解决方案3】:

      调试代码我意识到 org.hibernate.envers.event.spi.EnversIntegrator 中的“集成”方法也被调用了。事实上,我在 spring 配置中放错了“hibernate.listeners.envers.autoRegister”参数。这是我的工作配置:

      <bean id="entityManagerFactory"
          class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
          <property name="dataSource" ref="myTestDataSource" />
          <property name="packagesToScan" value="xyz.**.model" />
      
          <property name="jpaVendorAdapter" ref="jpaAdapter" />
          <property name="jpaProperties">
              <props>             
                            <prop key="hibernate.hbm2ddl.auto">validate</prop>
                  <prop key="hibernate.show_sql">false</prop>
                  <prop key="hibernate.format_sql">true</prop>
                  <prop key="hibernate.listeners.envers.autoRegister">false</prop>
              </props>
          </property>
          <property name="persistenceXmlLocation"
              value="classpath:spring/app-persistence.xml" />
      </bean>
      

      感谢亚当四,你的伟大作品。

      【讨论】:

        猜你喜欢
        • 2012-12-24
        • 1970-01-01
        • 2015-12-14
        • 2015-07-13
        • 2014-06-05
        • 2011-07-10
        • 2019-05-25
        • 2018-01-15
        • 2015-05-06
        相关资源
        最近更新 更多