Hibernate Tips: How to automatically set an attribute before persisting it


Take your skills to the next level!

The Persistence Hub is the place to be for every Java developer. It gives you access to all my premium video courses, monthly Java Persistence News, monthly coding problems, and regular expert sessions.


Hibernate Tips is a new series of posts in which I describe a quick and easy solution for common Hibernate questions. If you have a question you like me to answer, please leave a comment below.

Question:

I want to initialize an entity attribute automatically before it gets persisted. How can I execute custom code before Hibernate persists an entity?

Solution:

The JPA specification defines a set of callback annotations to trigger method calls for certain lifecycle events. If you want to initialize an entity attribute before it gets persisted, you just have to do 2 things:

  1. Add a method to the entity which initializes the attribute.
  2. Annotate this method with @PrePersist so that Hibernate calls it before it persists the entity.

You can see an example of such a method in the following code snippet.

@Entity
public class Author {

	…

	@PrePersist
	private void initializeCreatedAt() {
		this.createdAt = LocalDateTime.now();
		log.info(“Set createdAt to “+this.createdAt);
	}
}


Hibernate will call this method when it persists a new Author entity and trigger the initialization of the createdAt attribute. You can see that in the following log output. Hibernate calls the initializeCreatedAt method before it performs the SQL statements to get the primary key value and to persist the entity.

14:31:14,871 INFO [org.thoughts.on.java.model.Author] – Set createdAt to 2016-12-14T14:31:14.868
14:31:14,878 DEBUG [org.hibernate.SQL] – select nextval (‘hibernate_sequence’)
14:31:14,920 DEBUG [org.hibernate.SQL] – insert into Author (createdAt, firstName, lastName, version, id) values (?, ?, ?, ?, ?)
14:31:14,923 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] – binding parameter [1] as [TIMESTAMP] – [2016-12-14T14:31:14.868]
14:31:14,924 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] – binding parameter [2] as [VARCHAR] – [first name]
14:31:14,924 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] – binding parameter [3] as [VARCHAR] – [last name]
14:31:14,925 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] – binding parameter [4] as [INTEGER] – [0]
14:31:14,926 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] – binding parameter [5] as [BIGINT] – [1]

Learn More:

I get into more details about entity lifecycle events and the more advanced EntityListeners, in my Advanced Hibernate Training. I’m happy to see you there if you want to dive deeper into this topic.

The JPA specification also defines callback annotation for other entity lifecycle events. You can, for example, use the @PreRemove annotation to execute custom code before Hibernate deletes an entity, as I do in this post: How to implement a soft delete with Hibernate.

Hibernate Tips Book

Get more recipes like this one in my new book Hibernate Tips: More than 70 solutions to common Hibernate problems.

It gives you more than 70 ready-to-use recipes for topics like basic and advanced mappings, logging, Java 8 support, caching, and statically and dynamically defined queries.

Get it now!

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.