【问题标题】:Conditional Envers Auditing条件环境审计
【发布时间】:2012-12-24 09:48:49
【问题描述】:

我有一个要求,我只想在状态字段更改时审核记录。我已经按照文档章节教程“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);
    }   
}

类似的,我有

  • 插入EnversListener
  • UpdateEnversListener
  • 删除EnversListener
  • 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

【问题讨论】:

  • 目前发生了什么?是否调用了您的自定义集成器代码?
  • @adamw:我已将 sysout 语句添加到集成器代码中,但它们都没有出现。 JBOSS 似乎无法识别服务。我已经使用 Eclipse 4.2 Juno 作为动态 Web 项目创建了项目。 不确定 META-INF 的位置是否正确。任何建议..
  • 您是否检查了生成的 jar/war,是否将文件放在正确的位置?
  • @Adamw,抱歉延迟回复,是的 META-INF 位于 G:\jboss-as-web-7.0.2.Final\standalone\deployments\sample.war\META 的 WAR 文件中-INF\服务\
  • 而且这些类也直接在战争中,而不是在 .jar 中?

标签: hibernate jboss7.x hibernate-envers


【解决方案1】:

这是一个仅限 Spring 的解决方案,用于有条件的 Envers 审计,没有丑陋的 META-INF 文件夹等。您需要的只是配置类中的一个 bean 和一个 CustomEnversEventListener

@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 注册另一个监听器。

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

【讨论】:

    【解决方案2】:

    尝试将积分器文件放入:

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

    【讨论】:

      【解决方案3】:

      也许……

      在我的例子中,我使用 Maven,我必须在 pom.xml 中包含以下行:&lt;include&gt;**/*.Integrator&lt;/include&gt;,因为该文件未打包在 .ear 中。

      我的pom.xml

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

      【讨论】:

        【解决方案4】:

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

        【讨论】:

          【解决方案5】:

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

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2011-04-24
            • 2021-12-14
            • 2012-08-03
            • 2015-07-13
            • 2014-06-05
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多