JPA支持Java 8新的date和时间API

我为我的新项目使用Java 8。

我试图在java 8中使用新的date和时间api,但是我不知道JPA 2.1完全支持这个新的date和时间API或不。

请分享您的经验/意见在JPA的支持新的date和时间API在Java 8。

我可以安全地使用JPA 2.1在Java 8中使用新的date和时间api吗?

更新:

我正在使用Hibernate(4.3.5.Final)作为JPA实现。

JPA 2.1是一个在Java 1.8之前推出的规范,所以不要求任何支持。 显然有些实现可能支持一些Java 1.8特性。 有些Java 1.8字节码有问题(例如EclipseLink)。 我知道DataNucleus支持java.time和Java 1.8,因为这是我使用的。 你必须检查你的实现是什么样的支持水平。

有人要求JPA 2.2支持java.timetypes,请参阅https://java.net/jira/browse/JPA_SPEC-63

对于Hibernate 5.X只是添加

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

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

将无需任何额外的努力工作。 见https://hibernate.atlassian.net/browse/HHH-8844

更新:

请看看Jeff Morin的评论:自从Hibernate 5.2.x就足够了

  <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> 

请参阅https://github.com/hibernate/hibernate-orm/wiki/Migration-Guide—5.2和将Hibernate 5.2与Spring框架4.x集成

我在我的项目中使用Java 8,EclipseLink(JPA 2.1),PostgreSQL 9.3和PostgreSQL驱动程序-Postgresql-9.2-1002.jdbc4.jar,我可以使用新API的LocalDateTimevariables,但没有问题,但列的数据types是数据库中的bytea,所以你只能从Java应用程序中读取它,据我所知。 您可以使用AttributeConverter将新类转换为java.sql.Date我从Java.net中find这个代码

 @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(); } 

org.jadira.usertype可用于保存JSR 310date和时间API。

看看这个例子项目 。

从示例项目中,

 @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; } 

我知道这是一个老问题,但我想到了一个可能有用的替代解决scheme。

而不是尝试将新的java.time。*类映射到现有的数据库types,您可以利用@Transient:

 @Entity public class Person { private Long id; private Timestamp createdTimestamp; @Id @GeneratedValue public Long getId() { return id; } private Timestamp getCreatedTimestamp() { return createdTime; } private void setCreatedTimestamp(final Timestamp ts) { this.createdTimestamp = ts; } @Transient public LocalDateTime getCreatedDateTime() { return createdTime.getLocalDateTime(); } public void setCreatedDateTime(final LocalDateTime dt) { this.createdTime = Timestamp.valueOf(dt); } } 

您使用使用新的Java 8date/时间类的公共getter / setter方法,但在后台getter / setter使用旧版date/时间类。 当持久化实体时,遗留的date/时间属性将被保留,但不会保留新的Java 8属性,因为它使用@Transient进行了注释。

JPA 2.2支持java.time

JPA 2.2现在支持LocalDateOffsetTimeLocalDateTimeOffsetTimeOffsetDateTime

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

对于JPA 2.2实现,可以使用Hibernate 5.2EclipseLink 2.7

Hibernate 5支持比JPA 2.2更多的Javatypes,比如DurationInstantZonedDateTime

更多信息:

  • 如何使用 Thorben Janssen的JPA 2.2映射date和时间API
  • JPA 2.2有哪些新特性?
  • JSR 338(维护版本)
  • 维基百科

有很多办法可以做,也取决于你的框架工作:如果你的框架工作在现场转换器这样的spring做这样的:1-

 @DateTimeFormat(pattern = "dd.MM.yyyy - HH:mm") private Long createdDate; 

在这里我使用旧时代格式https://www.epochconverter.com/ epoch是非常灵活和可接受的格式

2-其他方法是使用jpa @PostLoad @PreUpdate @PrePersist

 @PostLoad public void convert() { this.jva8Date= LocalDate.now().plusDays(1); } 

或使用温度这样的

 @Transient public LocalDateTime getCreatedDateTime() { return createdTime.getLocalDateTime(); } 

对于typesTIMESTAMP,你可以使用这个转换器:

 @Converter(autoApply = true) public class LocalDateTimeAttributeConverter implements AttributeConverter<LocalDateTime, Timestamp> { @Override public Timestamp convertToDatabaseColumn(LocalDateTime datetime) { return datetime == null ? null : Timestamp.valueOf(datetime); } @Override public LocalDateTime convertToEntityAttribute(Timestamp timestamp) { return timestamp == null ? null : timestamp.toLocalDateTime(); } } 

对于DATEtypes,您可以使用此转换器:

 @Converter(autoApply = true) public class LocalDateAttributeConverter implements AttributeConverter<LocalDate, Date> { @Override public Date convertToDatabaseColumn(LocalDate date) { return date == null ? null : Date.valueOf(date); } @Override public LocalDate convertToEntityAttribute(Date date) { return date == null ? null : date.toLocalDate(); } } 

对于时间types你可以使用这个转换器:

 @Converter(autoApply = true) public class LocalTimeAttributeConverter implements AttributeConverter<LocalTime, Time> { @Override public Time convertToDatabaseColumn(LocalTime time) { return time == null ? null : Time.valueOf(time); } @Override public LocalTime convertToEntityAttribute(Time time) { return time == null ? null : time.toLocalTime(); } }