有条件的Envers审计

时间:2013-01-10 03:57:48

标签: hibernate jboss7.x hibernate-envers

我有一个要求,我只想在更改状态字段时审核记录。我已经按照文档章节教程“15.8。条件审核”。

步骤1:关闭自动Envers事件侦听器注册。我有以下内容:

<prop key="hibernate.listeners.envers.autoRegister">false</prop>

步骤2:为适当的事件侦听器创建子类。

public class DeleteEnversListener extends EnversPostDeleteEventListenerImpl {   
    private static final long serialVersionUID = 5906427978349712224L;
    private static Log log = LogFactory.getLog(DeleteEnversListener.class);

    public DeleteEnversListener(AuditConfiguration enversConfiguration) {
        super(enversConfiguration);
    }

    @Override
    public void onPostDelete(PostDeleteEvent event) {
        log.info("!!! just logging entity !! "+ event.getEntity());
        super.onPostDelete(event);
    }   
}

以类似的方式,我有

  • InsertEnversListener
  • UpdateEnversListener
  • DeleteEnversListener
  • CollectionRecreateEnversListener
  • PreCollectionRemoveEnversListener
  • PreCollectionUpdateEnversListener

第3步:创建自己的org.hibernate.integrator.spi.Integrator

实施
public class CustomEnversIntegrator extends EnversIntegrator   {

    private static Log log = LogFactory.getLog(CustomEnversIntegrator.class);

    @Override
    public void integrate(Configuration configuration,
            SessionFactoryImplementor sessionFactory,
            SessionFactoryServiceRegistry serviceRegistry) {

        super.integrate(configuration, sessionFactory, serviceRegistry);
        final AuditConfiguration enversConfiguration = AuditConfiguration.getFor( configuration, serviceRegistry.getService( ClassLoaderService.class ) );
        EventListenerRegistry listenerRegistry = serviceRegistry.getService( EventListenerRegistry.class );

        System.out.println("Registering event listeners");
        if (enversConfiguration.getEntCfg().hasAuditedEntities()) {
            listenerRegistry.appendListeners(EventType.POST_INSERT, new InsertEnversListener(enversConfiguration));
            listenerRegistry.appendListeners(EventType.POST_UPDATE, new UpdateEnversListener(enversConfiguration));
            listenerRegistry.appendListeners(EventType.POST_DELETE, new DeleteEnversListener(enversConfiguration ) );
            listenerRegistry.appendListeners(EventType.POST_COLLECTION_RECREATE, new CollectionRecreateEnversListener(enversConfiguration ) );
            listenerRegistry.appendListeners(EventType.PRE_COLLECTION_REMOVE, new PreCollectionRemoveEnversListener(enversConfiguration ) );
            listenerRegistry.appendListeners(EventType.PRE_COLLECTION_UPDATE, new PreCollectionUpdateEnversListener(enversConfiguration ) );
        }

    }
}

步骤4:要在Hibernate启动时自动使用集成器,您需要添加META-INF/services/org.hibernate.integrator.spi.Integrator文件。以下是org.hibernate.integrator.spi.Integrator文件

的内容
com.hib.sample.listener.CustomEnversIntegrator

我不确定,如果我遗失任何东西。我正在使用JBOSS AS 7.0和Hibernate 4.1.8

5 个答案:

答案 0 :(得分:2)

这里是针对条件Envers的审计的纯Spring解决方案,没有难看的META-INF文件夹等。您所需要的只是配置类中的Bean和CustomEnversEventListener。 / p>

@Bean
public EventListenerRegistry listenerRegistry(EntityManagerFactory entityManagerFactory) {
    ServiceRegistryImplementor serviceRegistry = entityManagerFactory.unwrap(SessionFactoryImpl.class).getServiceRegistry();

    final EnversService enversService = serviceRegistry.getService(EnversService.class);
    EventListenerRegistry listenerRegistry = serviceRegistry.getService(EventListenerRegistry.class);

    listenerRegistry.setListeners(EventType.POST_UPDATE, new CustomEnversEventListener(enversService));
    return listenerRegistry;
  }

  public class CustomEnversEventListener extends EnversPostUpdateEventListenerImpl {

    CustomEnversEventListener(EnversService enversService) {
      super(enversService);
    }

    @Override
    public void onPostUpdate(PostUpdateEvent event) {

      // custom conditional stuff

      super.onPostUpdate(event);
    }
  }

如果您只想自定义一个侦听器,即EnversPostUpdateEventListener,则无需禁用hibernate.listeners.envers.autoRegister即可让Envers注册另一个侦听器。

然后,您可以通过Envers覆盖listenerRegistry.setListeners侦听器,或通过listenerRegistry.appendListeners附加

答案 1 :(得分:1)

尝试将积分器文件放入:

sample.war\WEB-INF\classes\META-INF\services\...

答案 2 :(得分:0)

也许......

在我的情况下,我使用Maven,我必须在pom.xml中包含以下行:<include>**/*.Integrator</include>,因为该文件未打包在.ear中。

我的pom.xml

<resources>
       <resource>
           <directory>src/main/resources</directory>
           <filtering>true</filtering>
           <includes>
                <include>**/*.xml</include>
               <include>**/*.Integrator</include>
           </includes>
       </resource>
       ...

答案 3 :(得分:0)

META-INF / services / 下的 META-INF / services / 文件夹中创建文件 org.hibernate.integrator.spi.Integrator (包含我的自定义集成商的限定名称)我的maven项目的strong> src / main / resources 使我的自定义集成商代码被调用。

答案 4 :(得分:0)

@ComponentScan(basePackages = {“ com.example.demo”},lazyInit = true)

添加lazyInit = true,为我触发了自定义积分器。