如何将Java 8 OffsetTime
和OffsetDateTime
与Hibernate一起作为正确的SQL类型(TIME_WITH_TIMEZONE
和TIMESTAMP_WITH_TIMEZONE
)来维护?我在a blog中使用LocalTime
找到了LocalDateTime
和EnhancedUserType
的解决方案。
用户类型如何用于偏移数据?
答案 0 :(得分:2)
由于这是一个非常常见的问题,所以此答案基于this article,我写了用JPA映射日期和时间戳的最佳方法。
从2.2版开始,JPA支持映射Java 8 Date/Time API,例如LocalDateTime
,LocalTime
,LocalDateTimeTime
,OffsetDateTime
或OffsetTime
。 / p>
此外,即使使用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()
);
答案 1 :(得分:1)
从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/