Enable Javascript

Please enable Javascript to view website properly

Toll Free 1800 889 7020

Looking for an Expert Development Team? Take two weeks Trial! Try Now

Database Transaction Auditing using Spring Envers

Technology:

database-transaction

Spring Data is one module built on top of the spring framework for easy database transactions. It provides various interfaces, and annotation for easy outsource Java development. Spring data make use of @Repository annotation, one of the stereotypes of the annotation provided by the Spring framework for creating database access-related beans. We need to enable the spring data using @EnableJpaRepositories annotation. If we are using XML based namespaces, then we can use the below configuration:

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jpa="http://www.springframework.org/schema/data/jpa" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd"> <jpa:repositories base-package="com.example.repositories"/> </beans>

Alternatively, Spring data also provides @RepositoryDefinition annotation if we are not implementing the spring data interfaces.

In some cases, we used to write base interfaces across the application, for these interfaces, we won’t want to create spring beans for it, Spring data provides @NoRepositoryBean annotation for the same thing to exclude classes to create beans.

Database Auditing without using Spring framework Envers:

The JPA providers do not explicitly provide auditing, but we can achieve the auditing using lifecycle events.

JPA will provide @PrePersist, @PreUpdate and @PreRemove annotation for before transaction commits, and @PostPersist, @PostUpdate, @PostRemove annotations for after transaction commits.

We can use these annotations either at the entity level, or we can write these annotated methods in a separate class and we can provide at class level as entity listener.

public class AuditListener { @PrePersist private void beforeInsert(Object object) { ... } @PreUpdate private void beforeUpdate(Object object) { ... } @PreRemove private void beforeDelete(Object object) { ... } @PostPersist private void AfterInsert(Object object) { ... } @PostUpdate private void AfterUpdate(Object object) { ... } @PostRemove private void AfterDelete(Object object) { ... } } And Entity class will look like below: @EntityListeners(AuditListener.class) @Entity public class SampleEntity { // methods }

If we want to query for entity revision using JPA, we need to create audited entities also, need to implement all CRUD operations for it.

Database Auditing using Spring framework Envers:

If we use Spring Data JPA, it will provide an event listener for all operations, also it introduces one Repository implementation RevisionRepository interface for querying the Audited data.

Dependencies:

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-envers</artifactId> </dependency>

The above dependencies are required if we are using spring boot, if not we need to check for the compatible version for both libraries.

Enabling JPA Auditing in Spring Data JPA:

Spring Data Envers provides @EnableJpaAuditing annotation for bootstrapping Envers related beans, and AuditingEntityListener is the abstract listener for all our common auditing features.

Add this listener at class level, for those entities we want to enable the auditing, similar JPA implementation but listener class will be provided by Spring Data Envers.

@EntityListeners(AuditingEntityListener.class) @Entity public class SampleEntity { // methods }

For the Spring Data Repository interface implement the RevisionRepository interface for revision fetching.

Adding user principal information in Entity Audits:

If we are using Spring security, we can also track the changes made by the user, using the AuditAware interface.

For tracking the user changes need to annotate 2 of entity fields with @LastModifiedBy,@CreatedBy to track the changes.

And the values for these fields will be set by AuditAware interface implementation.

We need to create one bean of the AuditAware which is the implementation of this interface and provide the bean reference to @EnableJpaAuditing annotation as an argument.

class SpringSecurityAuditorAware implements AuditorAware < UserDetails > { publicUserDetailsgetCurrentAuditor() { Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); if (authentication == null || !authentication.isAuthenticated()) { return null; } return ((UserDetails) authentication.getPrincipal()).getUser(); } } @Configuration @EnableJpaAuditing(auditorAwareRef = "auditorProvider ") public class AuditConfig { @Bean AuditorAware < String > auditorProvider() { return new SpringSecurityAuditorAware(); } }

Tracking Creation Dates and Modification Dates:

Similar to @LastModifiedBy, @CreatedBy annotation, we have @CreatedDate, @LastModifiedDate annotations for tracking creation and modified dates.

As a best practice, move all these common fields to the base entity class and every Entity class must be extended this base entity class and it needs to be annotated with @MappedSuperClass annotation.

Conclusion:

JPA specification will not directly provide a way for auditing, but we can achieve through the event listeners, and we need to write a lot of code at each entity level to achieve it.

Spring Data Envers is one of the libraries which will eliminate the majority of repeated code by using annotations. Spring Data Envers provides a RevisionRepository interface for querying the audit history of the entity, and if we are using Spring security in our application, we can also track the changes done by a particular user using the AuditorAware interface.

Recent Blogs

Categories

NSS Note

Some of our clients

team