繁体   English   中英

如何使用 JPA 和 Hibernate 保留 OffsetTime 和 OffsetDateTime

[英]How to persist OffsetTime and OffsetDateTime with JPA and Hibernate

如何将 Java 8 OffsetTimeOffsetDateTime与 Hibernate 保持为正确的 SQL 类型( TIME_WITH_TIMEZONETIMESTAMP_WITH_TIMEZONE )? 我在博客中使用EnhancedUserType找到了LocalTimeLocalDateTime的解决方案。

用户类型如何用于偏移数据?

从 Hibernate ORM 5.3 开始实现 JPA 2.2 标准。

JPA 2.2 规范说现在支持以下 Java 8 类型:

  • java.time.LocalDate
  • java.time.LocalTime
  • java.time.LocalDateTime
  • java.time.OffsetTime
  • java.time.OffsetDateTime

因此,您可以使用表的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,像支持LocalDateTimeLocalTimeLocalDateTimeTimeOffsetDateTimeOffsetTime

此外,即使使用 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 对象,并且clockAlarmOffsetTime类型。

坚持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实体时,我们可以看到从数据库中正确获取了OffsetDateTimeOffsetTime

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM