Reputation: 185
I've created an entities copier in a project where envers is enable but for this copier I don't need the auditing: is there a way to disable temporarily the envers auditing?
I know that there are listener that works as interceptors (before the audit trigger) but I need also know where auditing is triggered from (for example the controller that call the service where auditing is triggered).
I don't know if it's possible.
Thanks
Upvotes: 3
Views: 2021
Reputation: 331
Envers registers a set of event listeners that are triggered by Hibernates Event system.
In order to implement conditional auditing (see envers documentation), you need to replace these listeners with your own implementation. The following event types trigger enver's listeners:
Since you want to skip auditing only on copied entities you only need to replace org.hibernate.envers.event.spi.EnversPostInsertEventListenerImpl
.
In your entity you add a transient field that acts as a flag. This way you can determine within your listener implementation if the entity was copied.
public class YourEntity {
@Transient
private boolean copy;
public boolean isCopy() {
return copy;
}
public void setCopy(boolean copy) {
this.copy = copy;
}
}
Then you implement your listener by extending the default one:
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);
}
}
In your copier you need to set the copy
flag for your entities.
public YourEntity copyEntity(YourEntity entityToCopy){
YourEntity newEntity;
//... your copy logic
newEntity.setCopy(true);
return newEntity;
}
Then you need to create your own implementation of org.hibernate.integrator.spi.Integrator. The Easiest is to extend 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));
}
}
}
Lastly you need to add your Integrator implementation in the META-INF/services/org.hibernate.integrator.spi.Integrator file.
com.your.project.audit.EnversCustomIntegrator
Upvotes: 1