简体   繁体   English

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

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

How can I persist Java 8 OffsetTime and OffsetDateTime with Hibernate as proper SQL types ( TIME_WITH_TIMEZONE and TIMESTAMP_WITH_TIMEZONE )?如何将 Java 8 OffsetTimeOffsetDateTime与 Hibernate 保持为正确的 SQL 类型( TIME_WITH_TIMEZONETIMESTAMP_WITH_TIMEZONE )? I found a solution for LocalTime and LocalDateTime using EnhancedUserType s in a blog .我在博客中使用EnhancedUserType找到了LocalTimeLocalDateTime的解决方案。

How would the user types be for offset data?用户类型如何用于偏移数据?

From Hibernate ORM 5.3 implements the JPA 2.2 standard.从 Hibernate ORM 5.3 开始实现 JPA 2.2 标准。

The JPA 2.2 specification says that the following Java 8 types are now supported: JPA 2.2 规范说现在支持以下 Java 8 类型:

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

So, you can use timestamp for the table as example:因此,您可以使用表的timestamp作为示例:

Entity you have:您拥有的实体:

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

Associated database table would be:关联的数据库表将是:

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

Reference: http://in.relation.to/2018/02/20/java8-date-time-mapping/参考: http : //in.relation.to/2018/02/20/java8-date-time-mapping/

Since version 2.2, JPA offers support for mapping Java 8 Date/Time API, like LocalDateTime , LocalTime , LocalDateTimeTime , OffsetDateTime or OffsetTime .自2.2版本,JPA提供了测绘的Java 8日期/时间API,像支持LocalDateTimeLocalTimeLocalDateTimeTimeOffsetDateTimeOffsetTime

Also, even with JPA 2.1, Hibernate 5.2 supports all Java 8 Date/Time API by default.此外,即使使用 JPA 2.1,Hibernate 5.2 默认也支持所有 Java 8 Date/Time API。

In Hibernate 5.1 and 5.0, you have to add the hibernate-java8 Maven dependency.在 Hibernate 5.1 和 5.0 中,您必须添加hibernate-java8 Maven 依赖项。

So, let's assume we have the following Notification entity:因此,让我们假设我们有以下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
}

Notice that the createdOn attribute is a OffsetDateTime Java object and the clockAlarm is of the OffsetTime type.请注意, createdOn属性是一个OffsetDateTime Java 对象,并且clockAlarmOffsetTime类型。

When persisting the Notification :坚持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 generates the proper SQL INSERT statement: Hibernate 生成正确的 SQL INSERT 语句:

INSERT INTO notification (
    notify_on, 
    created_on, 
    id
) 
VALUES (
    '07:30:00', 
    '2020-05-01 12:30:00.0', 
    1
)

When fetching the Notification entity, we can see that the OffsetDateTime and OffsetTime are properly fetched from the database:在获取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