A java.util.Date property can hold a date and time in a Java entity, but its database column needs a temporal mapping. Use @Temporal to choose whether the column stores a date, a time, or a timestamp. Without @Temporal, the default is TemporalType.TIMESTAMP. section 6.1.6
The three TemporalType options select the stored part of the value:
- DATE maps to a SQL DATE column. section 6.3.1 section 6.1.6
- TIME maps to a SQL TIME column. section 6.3.1 section 6.1.6
- TIMESTAMP maps to a SQL TIMESTAMP column. section 6.3.1 section 6.1.6
Listing 6.6 Property of a temporal type that must be annotated with @Temporal
@CreationTimestamp @Temporal(TemporalType.DATE) private Date createdOn; @UpdateTimestamp @Temporal(TemporalType.TIMESTAMP) private Date lastModified;
The entity-property example pairs @CreationTimestamp with DATE for createdOn and @UpdateTimestamp with TIMESTAMP for lastModified. The annotations make the intended database accuracy explicit. section 6.1.6
A property declared as java.util.Date need not load as that exact class. Hibernate returns java.sql.Date, java.sql.Time, or java.sql.Timestamp according to its temporal mapping. The JDBC subclasses preserve database accuracy: java.util.Date has millisecond accuracy, while java.sql.Timestamp can carry nanoseconds. This can make equals() comparisons between a java.util.Date and a loaded timestamp problematic. section 6.3.1
For new domain models, prefer the Java 8 java.time classes when they fit the required date or time value. JPA 2.2 supports them; java.util.Date remains relevant when mapping existing properties. section 6.3.1
