实施条件 Envers 审计 (Hibernate 4.3.7.Final)
Implementing Conditional Envers Auditing (Hibernate 4.3.7.Final)
我想审核我实体中的所有属性,但前提是某些属性已更改。
按照文档 (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 中添加一条新记录 table。
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 !!!!!
}
调用更新地址实体 booth 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 table 中创建这个新记录?
非常感谢!
您需要子类化事件侦听器,例如PostInsertEnversEventListener
,在那里做条件审计检查,如果检查通过就调用 super 方法。
调试代码我发现 org.hibernate.envers.event.spi.EnversIntegrator 中的 "integrate" 方法也被调用了。事实上,我在 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>
感谢 Adam 4 的出色工作。
对于较新的版本,属性 是 hibernate.envers.autoRegisterListeners
而不是 hibernate.listeners.envers.autoRegister
.
最后一个只是遗留的。您可以检查 EnversIntegrator
和 EnversServiceImpl
类。
对于 spring 引导,您可以设置为:
spring.jpa.properties.hibernate.envers.autoRegisterListeners=false
我想审核我实体中的所有属性,但前提是某些属性已更改。 按照文档 (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 中添加一条新记录 table。
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 !!!!!
}
调用更新地址实体 booth 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 table 中创建这个新记录?
非常感谢!
您需要子类化事件侦听器,例如PostInsertEnversEventListener
,在那里做条件审计检查,如果检查通过就调用 super 方法。
调试代码我发现 org.hibernate.envers.event.spi.EnversIntegrator 中的 "integrate" 方法也被调用了。事实上,我在 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>
感谢 Adam 4 的出色工作。
对于较新的版本,属性 是 hibernate.envers.autoRegisterListeners
而不是 hibernate.listeners.envers.autoRegister
.
最后一个只是遗留的。您可以检查 EnversIntegrator
和 EnversServiceImpl
类。
对于 spring 引导,您可以设置为:
spring.jpa.properties.hibernate.envers.autoRegisterListeners=false