Open In App

Auditing with Hibernate Envers in Spring Boot

Last Updated : 23 Jul, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

In modern applications, auditing plays a crucial role in tracking changes made to data over time. It allows developers and administrators to record who modified the data when it was changed, and what the previous values were. This is especially important for regulatory compliance, troubleshooting, and ensuring data integrity.

Hibernate Envers is a powerful auditing framework integrated with Hibernate, allowing developers to automatically track and log changes to entities without the need for custom audit tables and manual tracking. When integrated into a Spring Boot application, Hibernate Envers makes implementing an audit trail for entities easier, capturing essential information like insertions, updates, and deletions.

In this article, we will explore the key concepts of auditing, the benefits of using Hibernate Envers for auditing, and how to implement it in a Spring Boot application. We will also look at how to customize the auditing process to suit specific requirements.

Auditing

Auditing in the context of software applications refers to the process of tracking and recording the changes made to data over time. This involves keeping a historical record of data modifications, such as creations, updates, and deletions, along with relevant timestamps and user information.

Key Components of Auditing:

  • Change Tracking: Monitoring what changes are made to the data.
  • Versioning: Maintaining different versions of the data over time.
  • Metadata Recording: Capturing who made the changes and when they were made.
  • Historical Data Access: Providing mechanisms to retrieve past states of the data.

Why Auditing is Required?

Auditing serves multiple critical purposes in applications:

  • Compliance and Regulatory Requirements: Many industries, such as finance, healthcare, and government, are subject to strict regulations that mandate data auditing. Ensuring compliance helps avoid legal penalties and maintains trust with stakeholders.
  • Data Integrity and Security: Auditing helps detect unauthorized or malicious access by providing a trail of who accessed or modified data, ensuring that data remains accurate and reliable over time.
  • Troubleshooting and Debugging: When issues arise, audit logs can provide valuable insights into the sequence of events leading to the problem, facilitating efficient troubleshooting and debugging.
  • Historical Analysis and Reporting: Auditing data allows for historical analysis, trend identification, and comprehensive reporting, which can inform business decisions and strategies.
  • Accountability and Transparency: Auditing fosters accountability by attributing data changes to specific users or processes, promoting transparency within the organization.

Unique Facts About Auditing Using Hibernate Envers

Hibernate Envers simplifies the auditing process by automatically tracking entity changes and maintaining audit tables. Here’s what makes Hibernate Envers unique:

  • Seamless Integration with Hibernate ORM: Envers integrates tightly with Hibernate ORM, leveraging its mapping and session management capabilities. This ensures efficient and consistent auditing without significant overhead.
  • Annotation-Based Configuration: Using annotations like @Audited, developers can easily specify which entities and fields should be audited, reducing configuration complexity.
  • Automatic Audit Table Creation: Envers automatically generates and manages the audit tables corresponding to audited entities. These tables store the historical records of entity changes without manual intervention.
  • Versioning Support: Envers maintains different versions of the entities, allowing retrieval of entity states at any revision. This facilitates comprehensive historical data access.
  • Flexible Querying: It provides APIs to query historical data, such as retrieving revisions, tracking changes over time, and comparing different versions of entities.
  • Minimal Boilerplate Code: It handles auditing logic internally, minimizing the need for boilerplate code and allowing developers to focus on business logic.
  • Customization Capabilities: While Envers offers sensible defaults, it allows customization of auditing behavior, such as defining custom revision entities or excluding specific fields from auditing.

Using the In-built Auditing Mechanism in Spring Boot

Spring Boot, combined with Hibernate Envers and Spring Data JPA, provides robust auditing capabilities. Below are the steps to implement auditing in a Spring Boot application using Hibernate Envers.

Step 1: Create a New Spring Boot Project

Create a new Spring Boot project using IntelliJ IDEA. Choose the following options:

  • Name: spring-boot-audit-example
  • Language: Java
  • Type: Maven
  • Packaging: Jar

Click on the Next button.

Project Metadata

Step 2: Add the Dependencies

Add the following dependencies into the Spring Boot.

  • Spring Web
  • Spring Data JPA
  • MySQL Driver
  • Spring Boot DevTools

Click on the Create button.

Add Dependencies

External Dependency:

<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-envers -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-envers</artifactId>
<version>3.5.3-Final</version>
</dependency>

Project Structure

After the project creation done, the folder structure will look like the below image:

Project Folder Structure

Step 3: Configure Application Properties

Open the application.properties file and add the following configuration for MySQL and Hibernate Envers properties:

spring.application.name=spring-boot-audit-example
spring.datasource.url=jdbc:mysql://localhost:3306/audit_example
spring.datasource.username=root
spring.datasource.password=mypassword
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.ejb.interceptor=org.hibernate.envers.event.EnversIntegrator

Step 4: Create the User Class

Create the User entity that will be audited in your Spring Boot project.

User.java:

Java
package com.gfg.springbootauditexample;


import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.envers.Audited;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;


import java.time.LocalDateTime;

@Entity
@Audited
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

    private String email;
    @CreatedDate
    private LocalDateTime createdDate;

    @LastModifiedDate
    private LocalDateTime lastModifiedDate;
    
}

Step 5: Create the UserRepository Interface

Java
package com.gfg.springbootauditexample;

import org.springframework.data.jpa.repository.JpaRepository;

public interface UserRepository extends JpaRepository<User, Long> {
}

Step 6: Create the UserService Class

Create the UserService class to handle user-related operations in the Spring Boot application.

UserService.java:

Java
package com.gfg.springbootauditexample;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class UserService {

    @Autowired
    private UserRepository userRepository;

    public User saveUser(User user) {
        return userRepository.save(user);
    }

    public List<User> getAllUsers() {
        return userRepository.findAll();
    }

    public User getUserById(Long id) {
        return userRepository.findById(id).orElse(null);
    }

    public void deleteUser(Long id) {
        userRepository.deleteById(id);
    }
}

Step 7: Create the UserController Class

Create the UserController class to expose the user API endpoints of the Spring Boot application.

UserController.java:

Java
package com.gfg.springbootauditexample;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/api/users")
public class UserController {

    @Autowired
    private UserService userService;

    @PostMapping
    public ResponseEntity<User> createUser(@RequestBody User user) {
        return ResponseEntity.ok(userService.saveUser(user));
    }

    @GetMapping
    public List<User> getAllUsers() {
        return userService.getAllUsers();
    }

    @GetMapping("/{id}")
    public ResponseEntity<User> getUserById(@PathVariable Long id) {
        return ResponseEntity.ok(userService.getUserById(id));
    }

    @DeleteMapping("/{id}")
    public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
        userService.deleteUser(id);
        return ResponseEntity.noContent().build();
    }
}

Step 8: Main Class

No changes are required in the main class.

Java
package com.gfg.springbootauditexample;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;

@SpringBootApplication
@EnableJpaAuditing
public class SpringBootAuditExampleApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringBootAuditExampleApplication.class, args);
    }

}

pom.xml File:

XML
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="https://maven.apache.org/POM/4.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.3.4</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.gfg</groupId>
    <artifactId>spring-boot-audit-example</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>spring-boot-audit-example</name>
    <description>spring-boot-audit-example</description>
    <url/>
    <licenses>
        <license/>
    </licenses>
    <developers>
        <developer/>
    </developers>
    <scm>
        <connection/>
        <developerConnection/>
        <tag/>
        <url/>
    </scm>
    <properties>
        <java.version>17</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-envers -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-envers</artifactId>
            <version>3.5.3-Final</version>
        </dependency>



        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

Step 9: Run the Application

Once the project will be completed, it will run and start at port 8080. It will automatically create the necessary database tables, including the audit tables.

Project Running


Console Logs:

Console Logs

Step 10: Testing the Application

To test the auditing functionality, you can use tools like Postman or cURL to interact with the API endpoints:

1. Create a User

Make a POST request to /api/users with a JSON body.

POST http://localhost:8080/api/users

Output:

Create User

2. Get All Users

Make a GET request to /api/users to retrieve all users.

GET http://localhost:8080/api/users

Output:

Get All Users

3. Get a User by ID

Make a GET request to /api/users/{id} to retrieve a specific user.

GET http://localhost:8080/api/users/1

Output:

Get a User by ID

4. Delete User

Make a DELETE request to /api/users/{id} to delete a user.

DELETE http://localhost:8080/api/users/1

Output:

Delete User

User Table:

User Table

We have successfully set up the auditing with Hibernate Envers in the Spring Boot application. We can track changes made to the User entities over time, providing the robust solution for the auditing and versioning.

Conclusion

Implementing auditing with Hibernate Envers in Spring Boot provides a seamless way to track entity changes while ensuring compliance and enhancing data integrity. By leveraging annotations and automatic table management, Hibernate Envers simplifies the auditing process and allows developers to focus on building robust applications.


Similar Reads