提问者:小点点

Hibernate Envers 4.3迁移到5.0-条件envers审计


我的应用程序使用envers将数据写入_aud表,并将其包装到写入另一个表的xml中。我在Envers 4.3中使用条件审计来做到这一点。我的类扩展了EnversIntegrator

@Override   
public void integrate(Configuration configuration,SessionFactoryImplementor sessionFactory,SessionFactoryServiceRegistry serviceRegistry)
{  
    EventListenerRegistry listenerRegistry = serviceRegistry.getService( EventListenerRegistry.class );
    listenerRegistry.addDuplicationStrategy( EnversListenerDuplicationStrategy.INSTANCE );  
    final AuditConfiguration enversConfiguration = AuditConfiguration.getFor( configuration, serviceRegistry.getService( ClassLoaderService.class ) );  
    if (enversConfiguration.getEntCfg().hasAuditedEntities()) 
    {          
        listenerRegistry.appendListeners( EventType.POST_UPDATE, new PostUpdateListenerLog( enversConfiguration ) );
        listenerRegistry.appendListeners( EventType.POST_INSERT, new PostInsertListenerLog( enversConfiguration ) );
        listenerRegistry.appendListeners( EventType.POST_DELETE, new PostDeleteListenerLog( enversConfiguration ) );
    }   
}

在Envers 5.0中,AuditConfiguration被删除(https://github.com/hibernate/hibernate-orm/blob/5.0/migration-guide.adoc),以优先使用新的org. hibernate.envers.boot.内部.EnversService

所以我更改了我的代码,实现了新的Integrator接口

@Override
public void integrate(Metadata mtdt, SessionFactoryImplementor sfi, SessionFactoryServiceRegistry serviceRegistry) {

    EventListenerRegistry listenerRegistry = serviceRegistry.getService( EventListenerRegistry.class );
    listenerRegistry.addDuplicationStrategy( EnversListenerDuplicationStrategy.INSTANCE );  

    EnversService enversService = new EnversServiceImpl();
    if(enversService.getEntitiesConfigurations().hasAuditedEntities()) {
        listenerRegistry.appendListeners( EventType.POST_UPDATE, new PostUpdateListenerLog( enversService ) );
        listenerRegistry.appendListeners( EventType.POST_INSERT, new PostInsertListenerLog( enversService ) );
        listenerRegistry.appendListeners( EventType.POST_DELETE, new PostDeleteListenerLog( enversService ) );
    }

}

此代码不起作用,因为EnversService未初始化,给我一个

java. lang.IllegalStateException:服务尚未在org.hibernate.envers.boot.内部.EnversServiceImpl.getEntitiesConfigurations(EnversServiceImpl.java:253)初始化

我试图像使用旧的AuditConfiguration一样检索EnversService,但没有任何结果。我阅读了官方指南(http://docs.jboss.org/hibernate/orm/5.0/userguide/html_single/Hibernate_User_Guide.html),没有发现任何可以帮助我的东西。

我可以做些什么来检索可用于我的自定义侦听器的EnversService实例?

谢了安德鲁


共1个答案

匿名用户

我反编译org. hibernate.envers.boot.内部.EnversIntegrator类并找到解决方案。

@Override
public void integrate(Metadata metadata, SessionFactoryImplementor sessionFactory, SessionFactoryServiceRegistry serviceRegistry) {

    EventListenerRegistry listenerRegistry = serviceRegistry.getService( EventListenerRegistry.class );
    listenerRegistry.addDuplicationStrategy( EnversListenerDuplicationStrategy.INSTANCE );  

    EnversService enversService = serviceRegistry.getService(EnversService.class);
    if (!enversService.isInitialized()) {
        throw new HibernateException("Expecting EnversService to have been initialized prior to call to EnversIntegrator#integrate");
    }
    if(enversService.getEntitiesConfigurations().hasAuditedEntities()) {
        listenerRegistry.appendListeners( EventType.POST_UPDATE, new PostUpdateListenerLog( enversService ) );
        listenerRegistry.appendListeners( EventType.POST_INSERT, new PostInsertListenerLog( enversService ) );
        listenerRegistry.appendListeners( EventType.POST_DELETE, new PostDeleteListenerLog( enversService ) );
    }
}

问题解决!