|

Hibernate Tips: How to map a java.util.Date to a database column


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 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 use a java.util.Date to persist a date as an entity attribute.
But Hibernate maps it to a timestamp with nanoseconds. How can I change the mapping so that Hibernate only stores the years, months and days?

Solution:

The SQL standard supports three different data types to store date and time information. Hibernate can map all of them to a java.util.Date or a java.util.Calendar. You need to decide which of the following SQL types Hibernate shall use:

  • TIMESTAMP: Persists the date and time with nanoseconds. Hibernate uses this type by default.
  • TIME: Stores only the time of day without nanoseconds.
  • DATE: Persists only the date with years, months and days.

You can define the preferred mapping with the @Temporal annotation. As you can see in the following code snippet, it takes a TemporalType enum as a value. The enum allows you to select the SQL type (DATE, TIME or TIMESTAMP) which you want to use.

@Entity
public class Author {

	@Temporal(TemporalType.DATE)
	private Date dateOfBirth;
	...
}

As you can see in the following log output, the dateOfBirth attribute of the Author entity gets mapped to an SQL DATE without any time information.

07:22:50,453 DEBUG [org.hibernate.SQL] -
    select
        author0_.id as id1_0_0_,
        author0_.dateOfBirth as dateOfBi2_0_0_,
        author0_.firstName as firstNam3_0_0_,
        author0_.lastName as lastName4_0_0_,
        author0_.version as version5_0_0_
    from
        Author author0_
    where
        author0_.id=?
07:22:50,454 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] - binding parameter [1] as [BIGINT] - [1]
07:22:50,464 TRACE [org.hibernate.type.descriptor.sql.BasicExtractor] - extracted value ([dateOfBi2_0_0_] : [DATE]) - [1980-01-01]
07:22:50,465 TRACE [org.hibernate.type.descriptor.sql.BasicExtractor] - extracted value ([firstNam3_0_0_] : [VARCHAR]) - [John]
07:22:50,465 TRACE [org.hibernate.type.descriptor.sql.BasicExtractor] - extracted value ([lastName4_0_0_] : [VARCHAR]) - [Doe]
07:22:50,466 TRACE [org.hibernate.type.descriptor.sql.BasicExtractor] - extracted value ([version5_0_0_] : [INTEGER]) - [0]

Learn More:

Since Hibernate 5, you can also use the classes Java 8’s Date and Time API as entity attribute types. The new classes solve a lot of issues of the java.util.Date and provide all information Hibernate needs to map them to the correct JDBC types.
I explain the mapping of the Date and Time API classes in more details in: Hibernate 5: how to persist LocalDateTime and Co 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!