Spring Boot cookbook · Beginner

Track created/updated timestamps and users with JPA auditing

Automatically fill createdAt, updatedAt, createdBy and updatedBy on every entity.

Approach

Enable JPA auditing, extend a @MappedSuperclass with @CreatedDate, @LastModifiedDate, @CreatedBy, @LastModifiedBy, register AuditingEntityListener, and provide an AuditorAware that reads the current user from Spring Security.

Solution

@Configuration
@EnableJpaAuditing(auditorAwareRef = "auditor")
class AuditingConfig {
    @Bean
    AuditorAware<String> auditor() {
        return () -> Optional.ofNullable(SecurityContextHolder.getContext().getAuthentication())
                .filter(Authentication::isAuthenticated)
                .map(Authentication::getName)
                .or(() -> Optional.of("system"));
    }
}

@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public abstract class Auditable {
    @CreatedDate @Column(nullable = false, updatable = false) private Instant createdAt;
    @LastModifiedDate @Column(nullable = false) private Instant updatedAt;
    @CreatedBy @Column(updatable = false) private String createdBy;
    @LastModifiedBy private String updatedBy;
    // getters
}

@Entity
public class Invoice extends Auditable { /* ... */ }

Pitfalls

  • Using LocalDateTime without a zone — prefer Instant.
  • Expecting auditing for bulk @Modifying queries (they bypass entity listeners).
  • Treating these fields as a full audit trail (no history of changes).

Variations

  • Hibernate Envers for full revision history.
  • Database triggers or CDC for tamper-resistant audit logs.

Further reading: Spring Data JPA: Auditing

Reference: https://docs.spring.io/spring-data/jpa/reference/auditing.html

More Spring Boot recipes