[英]How to persist OffsetTime and OffsetDateTime with JPA and Hibernate
如何将 Java 8 OffsetTime
和OffsetDateTime
与 Hibernate 保持为正确的 SQL 类型( TIME_WITH_TIMEZONE
和TIMESTAMP_WITH_TIMEZONE
)? 我在博客中使用EnhancedUserType
找到了LocalTime
和LocalDateTime
的解决方案。
用户类型如何用于偏移数据?
从 Hibernate ORM 5.3 开始实现 JPA 2.2 标准。
JPA 2.2 规范说现在支持以下 Java 8 类型:
因此,您可以使用表的timestamp
作为示例:
您拥有的实体:
@Entity(name = "DateTimeEntity") public static class DateTimeEntity { @Id private Integer id; @Column(name = "duration_value") private Duration duration = Duration.of( 20, ChronoUnit.DAYS ); @Column(name = "instant_value") private Instant instant = Instant.now(); @Column(name = "local_date") private LocalDate localDate = LocalDate.now(); @Column(name = "local_date_time") private LocalDateTime localDateTime = LocalDateTime.now(); @Column(name = "local_time") private LocalTime localTime = LocalTime.now(); @Column(name = "offset_date_time") private OffsetDateTime offsetDateTime = OffsetDateTime.now(); @Column(name = "offset_time") private OffsetTime offsetTime = OffsetTime.now(); @Column(name = "zoned_date_time") private ZonedDateTime zonedDateTime = ZonedDateTime.now(); //Getters and setters omitted for brevity }
关联的数据库表将是:
create table DateTimeEntity ( id integer not null, duration_value bigint, instant_value timestamp, local_date date, local_date_time timestamp, local_time time, offset_date_time timestamp, offset_time time, zoned_date_time timestamp, primary key (id) )
参考: http : //in.relation.to/2018/02/20/java8-date-time-mapping/
自2.2版本,JPA提供了测绘的Java 8日期/时间API,像支持LocalDateTime
, LocalTime
, LocalDateTimeTime
, OffsetDateTime
或OffsetTime
。
此外,即使使用 JPA 2.1,Hibernate 5.2 默认也支持所有 Java 8 Date/Time API。
在 Hibernate 5.1 和 5.0 中,您必须添加hibernate-java8
Maven 依赖项。
因此,让我们假设我们有以下Notification
实体:
@Entity(name = "Notification")
@Table(name = "notification")
public class Notification {
@Id
private Long id;
@Column(name = "created_on")
private OffsetDateTime createdOn;
@Column(name = "notify_on")
private OffsetTime clockAlarm;
//Getters and setters omitted for brevity
}
请注意, createdOn
属性是一个OffsetDateTime
Java 对象,并且clockAlarm
是OffsetTime
类型。
坚持Notification
:
ZoneOffset zoneOffset = ZoneOffset.systemDefault().getRules()
.getOffset(LocalDateTime.now());
Notification notification = new Notification()
.setId(1L)
.setCreatedOn(
LocalDateTime.of(
2020, 5, 1,
12, 30, 0
).atOffset(zoneOffset)
).setClockAlarm(
OffsetTime.of(7, 30, 0, 0, zoneOffset)
);
entityManager.persist(notification);
Hibernate 生成正确的 SQL INSERT 语句:
INSERT INTO notification (
notify_on,
created_on,
id
)
VALUES (
'07:30:00',
'2020-05-01 12:30:00.0',
1
)
在获取Notification
实体时,我们可以看到从数据库中正确获取了OffsetDateTime
和OffsetTime
:
Notification notification = entityManager.find(
Notification.class, 1L
);
assertEquals(
LocalDateTime.of(
2020, 5, 1,
12, 30, 0
).atOffset(zoneOffset),
notification.getCreatedOn()
);
assertEquals(
OffsetTime.of(7, 30, 0, 0, zoneOffset),
notification.getClockAlarm()
);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.