Hibernate Envers
Spring Boot
configuration
auditing
Java persistence

Hibernate Envers with Spring Boot - configuration

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

Introduction

Hibernate Envers adds automatic audit history for entity changes, which is valuable for compliance, debugging, and traceability. In Spring Boot, configuration is straightforward, but small mapping mistakes can lead to missing revisions or startup errors. A clean setup includes dependency wiring, audited entity design, and predictable query access.

Add Dependencies and Enable Auditing

Include Envers alongside JPA and your database driver. Spring Boot auto-configuration handles most wiring if dependencies are present.

xml
1<dependencies>
2  <dependency>
3    <groupId>org.springframework.boot</groupId>
4    <artifactId>spring-boot-starter-data-jpa</artifactId>
5  </dependency>
6  <dependency>
7    <groupId>org.hibernate.orm</groupId>
8    <artifactId>hibernate-envers</artifactId>
9  </dependency>
10  <dependency>
11    <groupId>org.postgresql</groupId>
12    <artifactId>postgresql</artifactId>
13    <scope>runtime</scope>
14  </dependency>
15</dependencies>

Then annotate entities that need audit tracking.

java
1import jakarta.persistence.*;
2import org.hibernate.envers.Audited;
3
4@Entity
5@Audited
6public class Account {
7    @Id
8    @GeneratedValue(strategy = GenerationType.IDENTITY)
9    private Long id;
10
11    private String owner;
12    private String status;
13
14    // getters and setters
15}

Envers will create audit tables and revision metadata automatically.

Configure Envers Behavior

Use application properties to tune naming and storage behavior.

yaml
1spring:
2  jpa:
3    hibernate:
4      ddl-auto: update
5    properties:
6      org:
7        hibernate:
8          envers:
9            audit_table_suffix: _AUD
10            store_data_at_delete: true

A consistent naming strategy helps operations teams inspect audit data directly when needed.

Query Revision History

Use AuditReader to fetch historical states. This is useful for timeline views and incident analysis.

java
1import jakarta.persistence.EntityManager;
2import org.hibernate.envers.AuditReader;
3import org.hibernate.envers.AuditReaderFactory;
4
5public class AccountAuditService {
6
7    private final EntityManager em;
8
9    public AccountAuditService(EntityManager em) {
10        this.em = em;
11    }
12
13    public Account findRevision(Long id, Number revision) {
14        AuditReader reader = AuditReaderFactory.get(em);
15        return reader.find(Account.class, id, revision);
16    }
17}

Keep audit query code in dedicated services to avoid leaking revision logic into controllers.

Managing Exclusions and Large Fields

Not every field should be audited. Mark noisy or sensitive fields with @NotAudited.

java
1import org.hibernate.envers.NotAudited;
2
3@NotAudited
4private String transientToken;

Use this carefully so important compliance fields remain tracked.

Testing Audit Behavior

A basic integration test confirms revisions are created.

java
1import org.junit.jupiter.api.Test;
2import org.springframework.beans.factory.annotation.Autowired;
3import org.springframework.boot.test.context.SpringBootTest;
4import org.springframework.transaction.annotation.Transactional;
5
6@SpringBootTest
7class EnversTest {
8
9    @Autowired
10    private AccountRepository repo;
11
12    @Test
13    @Transactional
14    void createsRevisions() {
15        Account a = new Account();
16        a.setOwner("Ana");
17        a.setStatus("NEW");
18        repo.save(a);
19
20        a.setStatus("ACTIVE");
21        repo.save(a);
22    }
23}

Pair this with revision read assertions for stronger coverage.

Revision Metadata and User Tracking

Many teams need to know who changed a record, not only what changed. Envers supports custom revision entities so you can store actor identity and request metadata.

java
1import jakarta.persistence.*;
2import org.hibernate.envers.RevisionEntity;
3import org.hibernate.envers.RevisionNumber;
4import org.hibernate.envers.RevisionTimestamp;
5
6@Entity
7@RevisionEntity
8public class RevInfo {
9    @Id
10    @GeneratedValue
11    @RevisionNumber
12    private int id;
13
14    @RevisionTimestamp
15    private long ts;
16
17    private String actor;
18}

Populate actor from request context in a revision listener. This makes audit records useful for compliance and incident response.

Operational Considerations

Audit tables grow continuously. Plan retention and indexing from the start. Useful practices include:

  • Index foreign keys and revision columns.
  • Partition large audit tables if database supports it.
  • Define retention policy based on legal requirements.
sql
CREATE INDEX idx_account_aud_rev ON account_AUD (REV);

Without storage planning, Envers can become a hidden performance and maintenance cost.

Migration Strategy for Existing Data

If you introduce Envers into an existing system, decide whether historical backfill is required. Some teams start auditing from migration date only. Others run backfill jobs for critical entities. Document this decision clearly so consumers of audit data understand historical limits.

Common Pitfalls

  • Forgetting @Audited on entities expected to produce history.
  • Auditing volatile fields and bloating audit tables.
  • Relying on audit data without integration tests.
  • Mixing manual audit tables with Envers for the same entities.
  • Ignoring audit table growth and retention planning.

Summary

  • Add Envers dependency and annotate entities with @Audited.
  • Configure naming and delete behavior through properties.
  • Query history with AuditReader in service-level code.
  • Exclude nonessential fields to control audit volume.
  • Validate revision behavior with integration tests.

Related reading
Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

All Rights Reserved.