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

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!


Related Articles

Responses

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.