Setting a default value for a createdDateTime
field in a JPA entity is a common requirement in many applications. It ensures that every new record automatically has a creation timestamp. This can be handled in both JPA (Java code) and PostgreSQL (database schema). Let’s walk through the best way to do it using @PrePersist
and PostgreSQL’s default CURRENT_TIMESTAMP
.
1. Define the Entity Class with @PrePersist
In the JPA entity, we use the @PrePersist
lifecycle hook to automatically assign the current date and time when an entity is saved for the first time.
java
import javax.persistence.*;
import java.time.LocalDateTime;
@Entity
public class MyEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "created_date_time", nullable = false, updatable = false)
private LocalDateTime createdDateTime;
@PrePersist
protected void onCreate() {
this.createdDateTime = LocalDateTime.now();
}
// Getters and setters
public Long getId() {
return id;
}
public LocalDateTime getCreatedDateTime() {
return createdDateTime;
}
public void setCreatedDateTime(LocalDateTime createdDateTime) {
this.createdDateTime = createdDateTime;
}
}
2. Add a Default Value in PostgreSQL
Even though JPA handles the default timestamp at the Java level, it's good practice to set a default value in the database as well — especially to cover cases where data is inserted directly into the database.
Here’s how you can alter the table to add a default value for the created_date_time
column:
sql
ALTER TABLE my_entity
ADD COLUMN created_date_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL;
This ensures that even if JPA doesn't set the value, PostgreSQL will.
3. Combining JPA and PostgreSQL for Robustness
By using both @PrePersist
in the entity and setting a default in PostgreSQL, you cover:
- ORM-based inserts (
@PrePersist
sets the time). - Direct SQL inserts (PostgreSQL default kicks in).
4. Full Spring Boot Example
Dependencies (pom.xml):
xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
application.properties:
properties
spring.datasource.url=jdbc:postgresql://localhost:5432/mydatabase
spring.datasource.username=myusername
spring.datasource.password=mypassword
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
Repository:
java
import org.springframework.data.jpa.repository.JpaRepository;
public interface MyEntityRepository extends JpaRepository<MyEntity, Long> {
}
Controller:
java
import org.springframework.web.bind.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;
@RestController
@RequestMapping("/entities")
public class MyEntityController {
@Autowired
private MyEntityRepository repository;
@PostMapping
public MyEntity create(@RequestBody MyEntity entity) {
return repository.save(entity);
}
@GetMapping
public List<MyEntity> getAll() {
return repository.findAll();
}
}
Conclusion
To reliably set a default createdDateTime
in JPA with PostgreSQL:
- Use
@PrePersist
in the entity class to set the timestamp before saving. - Define a
DEFAULT CURRENT_TIMESTAMP
in the PostgreSQL schema to back it up. - This ensures consistent behavior whether your data is inserted via JPA or SQL.
This is a solid best-practice approach for audit fields like createdDateTime
.