Explain Codes LogoExplain Codes Logo

Creation timestamp and last update timestamp with Hibernate and MySQL

java
localdatetime
hibernate
timestamps
Anton ShumikhinbyAnton Shumikhin·Aug 3, 2024
TLDR

To set automatic creation and update timestamps, luaLeverage Hibernate's @CreationTimestamp and @UpdateTimestamp annotations:

import org.hibernate.annotations.CreationTimestamp; import org.hibernate.annotations.UpdateTimestamp; import java.util.Date; import javax.persistence.*; @Entity public class MyEntity { // ... other fields ... @Column(updatable = false) @CreationTimestamp private Date createdAt; @UpdateTimestamp private Date updatedAt; // ... getters and setters ... }

@CreationTimestamp sets the creation date once upon insert, while @UpdateTimestamp updates the last modified date with every save, and that's all the magic you need!

Handling timestamps like boss

Say no to Date and yes to LocalDateTime

Embrace LocalDateTime over Date for a robust time API:

import java.time.LocalDateTime; // ... @Column(updatable = false) @CreationTimestamp private LocalDateTime createdAt; @UpdateTimestamp private LocalDateTime updatedAt;

This helps you get over the old Date issues, providing a better grip over time just like a seasoned timelord!

Timezone consciousness in Hibernate

Use the hibernate.jdbc.time_zone configuration to ensure consistent timestamps across timezones:

hibernate.jdbc.time_zone = UTC

This sets timestamps in UTC, eliminating the nightmare of timezone errors. Remember, time is relative!

Power to the developer: Auditing with JPA and Hibernate

Using external listener classes

Use @EntityListeners to strap classes like AuditListener on your entities, separating the auditing logic:

import javax.persistence.EntityListeners; @EntityListeners(AuditListener.class) public class MyEntity { // ... fields ... }

DRY your code, rain inside the database

Create a base class with @MappedSuperclass, equipped with common timestamp fields. This ensures you are following DRY principles:

@MappedSuperclass public abstract class TimestampedEntity { @CreationTimestamp private LocalDateTime createdAt; @UpdateTimestamp private LocalDateTime updatedAt; }

Now, each entity inheriting this becomes a TimestampedEntity, no additional annotations necessary. Isn't that neat!

Timestamp management: Database vs. ORM

Controlling time at database-level

MySQL's CURRENT_TIMESTAMP() function coupled with DB triggers can be used for controlling timestamps, but note, with great power comes great responsibility!

CREATE TRIGGER before_insert_myentity BEFORE INSERT ON MyEntity FOR EACH ROW SET NEW.createdAt = CURRENT_TIMESTAMP;

Controlling time at ORM-level

Hibernate going rogue! Using @PrePersist and @PreUpdate annotations, Hibernate takes charge of timestamp:

@PrePersist protected void onCreate() { createdAt = LocalDateTime.now(); } @PreUpdate protected void onUpdate() { updatedAt = LocalDateTime.now(); }

This might call for more developer intervention, but lets you add custom logic, just like adding secret sauce to your favorite dish!

Chronicles of a seasoned coder: Performance and maintainability

Considering performance

Choosing the right method is critical. ORM control provides nimbleness but can hog resources. Database triggers are swift, but run the risk of becoming black boxes. Choose wisely!

Naming the troopers

Adopt clear column names such as create_date and modify_date to enhance maintainability. After all, what's in a name? Everything!

Mandatory timestamps

Ensure nullable = false for time fields, avoiding data integrity issues:

@Column(nullable = false, updatable = false) @CreationTimestamp private LocalDateTime createdAt; @Column(nullable = false) @UpdateTimestamp private LocalDateTime updatedAt;