问题描述
我在一个启用了 envers 的项目中创建了一个实体复制器,但对于这个复制器,我不需要审计:有没有办法暂时禁用 envers 审计?
我知道有侦听器可以作为拦截器(在审计触发器之前),但我还需要知道从哪里触发审计(例如调用触发审计的服务的控制器)。
我不知道这是否可能。
谢谢
解决方法
Envers 注册了一组由 Hibernates Event system 触发的事件监听器。
为了实现条件审计(see envers documentation),您需要将这些侦听器替换为您自己的实现。以下 event types 会触发 enver 的侦听器:
- EventType.POST_INSERT
- EventType.PRE_UPDATE
- EventType.POST_UPDATE
- EventType.POST_DELETE
- EventType.POST_COLLECTION_RECREATE
- EventType.PRE_COLLECTION_REMOVE
- EventType.PRE_COLLECTION_UPDATE
由于您只想跳过对复制实体的审核,因此您只需替换 org.hibernate.envers.event.spi.EnversPostInsertEventListenerImpl
。
在您的实体中,您添加一个临时字段作为标志。通过这种方式,您可以在侦听器实现中确定实体是否被复制。
public class YourEntity {
@Transient
private boolean copy;
public boolean isCopy() {
return copy;
}
public void setCopy(boolean copy) {
this.copy = copy;
}
}
然后你通过扩展默认监听器来实现你的监听器:
public class CustomPostInsertListener extends EnversPostInsertEventListenerImpl {
public CustomPostInsertListener(EnversService enversService) {
super(enversService);
}
@Override public void onPostInsert(PostInsertEvent event) {
if (event.getEntity() instanceof YourEntity
&& ((YourEntity) event.getEntity()).isCopy()) {
// Ignore this entity
return;
}
super.onPostInsert(event);
}
}
在您的复印机中,您需要为实体设置 copy
标志。
public YourEntity copyEntity(YourEntity entityToCopy){
YourEntity newEntity;
//... your copy logic
newEntity.setCopy(true);
return newEntity;
}
然后您需要创建自己的 org.hibernate.integrator.spi.Integrator 实现。最简单的方法是扩展 org.hibernate.envers.event.spi.EnversIntegrator
:
package com.your.project.audit;
public class EnversCustomIntegrator extends EnversIntegrator {
public static final String AUTO_REGISTER = "hibernate.listeners.envers.autoRegister";
private AuditConfiguration enversConfiguration;
@Override
public void integrate(org.hibernate.cfg.Configuration configuration,SessionFactoryImplementor sessionFactory,SessionFactoryServiceRegistry serviceRegistry) {
final EventListenerRegistry listenerRegistry = serviceRegistry.getService(EventListenerRegistry.class);
listenerRegistry.addDuplicationStrategy(EnversListenerDuplicationStrategy.INSTANCE);
enversConfiguration = AuditConfiguration.getFor(configuration,serviceRegistry.getService(ClassLoaderService.class));
if (enversConfiguration.getEntCfg().hasAuditedEntities()) {
listenerRegistry.appendListeners(EventType.POST_DELETE,new EnversPostDeleteEventListenerImpl(enversConfiguration));
listenerRegistry.appendListeners(EventType.POST_INSERT,new CustomPostInsertListener(enversConfiguration));
listenerRegistry.appendListeners(EventType.POST_UPDATE,new EnversPostUpdateEventListenerImpl(enversConfiguration));
listenerRegistry.appendListeners(EventType.POST_COLLECTION_RECREATE,new EnversPostCollectionRecreateEventListenerImpl(enversConfiguration));
listenerRegistry.appendListeners(EventType.PRE_COLLECTION_REMOVE,new EnversPreCollectionRemoveEventListenerImpl(enversConfiguration));
listenerRegistry.appendListeners(EventType.PRE_COLLECTION_UPDATE,new EnversPreCollectionUpdateEventListenerImpl(enversConfiguration));
}
}
}
最后,您需要在 META-INF/services/org.hibernate.integrator.spi.Integrator 文件中添加您的 Integrator 实现。
com.your.project.audit.EnversCustomIntegrator