Maintain the data versioning info with Spring Data — Envers

Denuwan Himanga Hettiarachchi
3 min readFeb 9, 2020

Hi Folks,

Hibernate Envers project aimed to track data changes at the entity level with easy configurations in properties level and entity class level using annotations. The spring-data-envers project builds on top of Hibernate Envers and comes up as an extension of the Spring Data JPA project. In this quick tutorial, I’ll demonstrate the minimum configuration needed to implement spring-data-envers auditing features in your Spring Boot REST service.

Demo

In this demo, I’ll implement a simple blog service that includes user’s data, posts data, comments data, images data and category data. Following the ER diagram depict the relationship between each entity.

ER Diagram before implement the Spring Data — Envers
  1. Minimum dependencies need to implement the project.
pom.xml

2. Entity level configuration

Now you need to identify the parent entity class, which you need to maintain the versioning information. In this scenario, my focus is to track the post entity changes including user entity and image entity changes. I’m not going to maintain category and comment entities.

Based on the requirements, the Post entity class should be annotated using @Audited annotation and using @NotAudited annotation I can simply ignore the tracking category and comment entity changes.

Also, make sure to put @Audited annotations to the child level entities aswell. In this scenario, I need to annotate the user and images entities using @Auditedannotation in the entity class level.

Post.java

3. Repository interface level configuration

In Post repository interface, we need to extend from RevisionRepository<Post,Integer,Integer>. By implementing RevisionRepository allows the following 4 different methods to get versioning information belongs to the Post entity class.

  • findLastChangeRevision(ID id) — Returns the revision of the entity it was last changed in.
  • findRevisions(ID id) — Returns all Revisions of an entity with the given id.
  • findRevisions(ID id, Pageable pageable) — Returns a Page of revisions for the entity with the given id. Note, that it’s not guaranteed that implementations have to support sorting by all properties.
  • findRevision(ID id, N revisionNumber) — Returns the entity with the given ID in the given revision number.

4. Providing RepositoryFactoryBeanClass

We need to mention the repository factory bean at the root level class which is annotated as @SpringBootApplication of the Spring Boot project This configuration allows integrating spring-data-envers project to your Spring Boot project.

@EnableJpaRepositories(repositoryFactoryBeanClass = EnversRevisionRepositoryFactoryBean.class)

Once you have done all the required configurations, you can simply run your Spring Boot application by changing the ddl-auto property as an update. Envers take care of all the table creation on behalf of you. But in production, you can use the generated tables if your project does not prefer the auto table creation feature.

In this scenario, Envers create the following tables based on our configuration.

ER Diagram after implementing the Spring Data — Envers

Envers allow configuration changes to customized versioning features compatible with our project naming conventions. We can customized history table prefix, suffix, and a few other naming conventions by changing the following properties.

  • Spring.jpa.properties.org.hibernate.envers.audit_table_prefix — Change history table prefix
  • Spring.jpa.properties.org.hibernate.envers.audit_table_suffix — Change history table suffix (Default value — _AUD)
  • Spring.jpa.properties.org.hibernate.envers.revision_field_name — Change the name of the filed which is maintained version number (Default value — REV)
  • Spring.jpa.properties.org.hibernate.envers.revision_type_field_name — Change the name of the filed which is maintained change type (Update/Delete/Create) (Default value — REVTYPE)

Hope this quick demo helps to understand the Envers features and capabilities which we can use to simply implement auditing feature in our Spring Boot project. The Envers framework has its own limitations and behaviors based on your entity-level mapping. If you are facing unexpected behavior in versioning data make sure to revalidate table level mappings (Usually in Bi-Directional mappings) and Cascade type properties.

Demo project available on GIT

Happy Coding…

--

--