Lifecycle callbacks and auditing

Hibernate · lesson 22 of 32 · 3 min read

Stamp created and updated columns automatically, and know exactly when each hook runs.

Open this lesson in the learning hub

Key points

  • JPA gives you @PrePersist, @PreUpdate and @PreRemove, their @Post twins, and @PostLoad after a read.
  • @PreUpdate only fires when dirty checking found a real change. No change means no UPDATE and no callback.
  • Callbacks run inside the flush. Never call a repository, publish an event or touch another entity from one.
  • Spring Data auditing is tidier: @CreatedDate, @LastModifiedDate and @CreatedBy on a base class.
  • It needs @EnableJpaAuditing, @EntityListeners on the class, and an AuditorAware bean for the user.
  • Two timestamps are not history. For who changed what, and when, add Hibernate Envers and get a real revision table.

Example

@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public abstract class Auditable {

    @CreatedDate      @Column(updatable = false) private Instant createdAt;
    @LastModifiedDate                            private Instant updatedAt;
    @CreatedBy        @Column(updatable = false) private String createdBy;
}

@Entity
public class Book extends Auditable {

    @Id @GeneratedValue private Long id;
    private String title;
    private String slug;

    @PrePersist
    @PreUpdate
    void normalise() {                 // pure, local, no other entity touched
        this.slug = title.toLowerCase().replace(" ", "-");
    }
}

@Configuration
@EnableJpaAuditing
class AuditConfig {
    @Bean
    AuditorAware<String> auditorAware() {
        return () -> Optional.ofNullable(SecurityContextHolder.getContext())
                             .map(c -> c.getAuthentication().getName());
    }
}

Let the framework stamp the audit columns; keep your own callbacks local.

This is a reading copy. The full lesson — with the visual explainer, the interactive lab and a Run button for the code — lives in the Hibernate course, and every lesson in it is listed on the Hibernate contents page.