Sum_Pie
Sum_Pie

Reputation: 185

Hibernate Envers: disable auditing temporarily

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

Answers (1)

Madlemon
Madlemon

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:

  • EventType.POST_INSERT
  • EventType.PRE_UPDATE
  • EventType.POST_UPDATE
  • EventType.POST_DELETE
  • EventType.POST_COLLECTION_RECREATE
  • EventType.PRE_COLLECTION_REMOVE
  • EventType.PRE_COLLECTION_UPDATE

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

Related Questions