JPA support for Java 8 new date and time API

Solution 1:

For Hibernate 5.X just add

    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-java8</artifactId>
        <version>${hibernate.version}</version>
    </dependency>

and

@NotNull
@Column(name = "date_time", nullable = false)
protected LocalDateTime dateTime;

will work without any additional effort. See https://hibernate.atlassian.net/browse/HHH-8844

UPDATE:

Please have a look at Jeff Morin comment: since Hibernate 5.2.x it is enough

 <dependency>
     <groupId>org.hibernate</groupId>
     <artifactId>hibernate-core</artifactId>
     <version>5.2.1.Final</version>
 </dependency>
 <dependency>
     <groupId>org.springframework</groupId>
     <artifactId>spring-...</artifactId>
     <version>4.3.1.RELEASE</version>
 </dependency>

See https://github.com/hibernate/hibernate-orm/wiki/Migration-Guide---5.2 and Integrate Hibernate 5.2 with Spring framework 4.x

Solution 2:

JPA 2.1 is a spec that came out before Java 1.8, so doesn't mandate any support for it. Obviously some implementations may support some Java 1.8 features. Some have problems with Java 1.8 bytecode (e.g EclipseLink). I know DataNucleus supports java.time and Java 1.8 since that's the one I use. You'd have to check your implementation for what its support level is.

It has been requested that JPA 2.2 support the java.time types, see this issue https://java.net/jira/browse/JPA_SPEC-63

Solution 3:

JPA 2.2 supports java.time

JPA 2.2 now supports LocalDate, LocalTime, LocalDateTime, OffsetTime and OffsetDateTime.

<dependency>
  <groupId>javax.persistence</groupId>
  <artifactId>javax.persistence-api</artifactId>
  <version>2.2</version>
</dependency>

For JPA 2.2 implementation, Hibernate 5.2 or EclipseLink 2.7 can be used.

Hibernate 5 supports more java types than JPA 2.2 like Duration, Instant and ZonedDateTime.

More Info:

  • How To Map The Date And Time API with JPA 2.2 by Thorben Janssen
  • What’s new in JPA 2.2
  • JSR 338 (Maintenance Release)
  • JPA 2.2 Wiki

Solution 4:

org.jadira.usertype can be used to persist JSR 310 Date and Time API.

Check out this example project.

From Example Project,

@MappedSuperclass
public class AbstractEntity {

    @Id @GeneratedValue Long id;

    @CreatedDate//
    @Type(type = "org.jadira.usertype.dateandtime.threeten.PersistentZonedDateTime")//
    ZonedDateTime createdDate;

    @LastModifiedDate//
    @Type(type = "org.jadira.usertype.dateandtime.threeten.PersistentZonedDateTime")//
    ZonedDateTime modifiedDate;
}

Solution 5:

I am using Java 8, EclipseLink(JPA 2.1), PostgreSQL 9.3 and PostgreSQL Driver -Postgresql-9.2-1002.jdbc4.jar in my project and I can use LocalDateTime variables from the new API with no error, but the data type of the column will be bytea in the database. You can only read it from a Java application as far i know.

However, you can use AttributeConverter to convert these classes to java.sql.Date. I found this code from Java.net

@Converter(autoApply = true)
public class LocalDatePersistenceConverter implements
AttributeConverter {
@Override
public java.sql.Date convertToDatabaseColumn(LocalDate entityValue) {
    return java.sql.Date.valueOf(entityValue);
}

@Override
public LocalDate convertToEntityAttribute(java.sql.Date databaseValue) {
    return databaseValue.toLocalDate();
}