Postgres中没有时区DEFAULT CURRENT_TIMESTAMP的字段TIMESTAMP的JPA模型类?

时间:2019-07-08 15:21:55

标签: java postgresql spring-boot postgresql-11 jpa-2.2

我在Postgres中的Table下方,并在Spring Boot 2.1.6.RELEASE 中使用 Java 8和Postgres-11 。我已经浏览过链接:How to map timestamp column to JPA type?Hibernate creates column without name when using "default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP",但是我真的很想使用Java 8 Date API而不是Java 7。

CREATE TABLE note(
    note_id serial PRIMARY KEY,
    message varchar(255) NOT NULL,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);

我已经创建了如下所示的模型类,但是与我需要的不匹配。有帮助吗?

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode(callSuper = true)
@Entity
public class Note extends AuditEnabledEntity{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "note_id")
    private int noteId;

    @Column(name = "message")
    private String message;

    @Column(name = "created_at")
    private LocalDateTime createdAt;
}

1 个答案:

答案 0 :(得分:1)

Table of all date-time types in Java (both modern & legacy) as well as SQL standard.

类型错误

LocalDateTime是错误的类型。该类不能代表片刻,如其Javadoc中所述。

该类故意没有时区或从UTC偏移的概念。因此它代表一个日期和时间,例如“ 2019年1月23日中午”,但不知道在东京,巴黎或蒙特利尔是否是中午,例如,三个非常不同的时刻相距几个小时。因此,此类型适用于标准SQL类型TIMESTAMP WITHOUT TIME ZONE –不带 ,而不适合带 with

有关更多讨论,请参见:What's the difference between Instant and LocalDateTime?

右类型

对于标准SQL类型TIMESTAMP WITH TIME ZONE,您应该使用Java类型InstantOffsetDateTimeZonedDateTime。在这三个版本中,JDBC 4.2仅需要支持第二个OffsetDateTime

检索。

OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;

从Postgres检索的值将始终为UTC。 SQL标准未指定此行为,因此数据库各不相同。在Postgres中,发送到类型TIMESTAMP WITH TIME ZONE的字段的任何值都将调整为UTC。检索的值以UTC为单位。

存储。

myPreparedStatement.setObject( … , odt ) ;

从UTC(零偏移)调整到特定地区(时区)的人们使用的挂钟时间。

ZoneId z = ZoneId.of( "Asia/Tokyo" ;
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;

JPA

我不使用JPA,而是希望保持简单。

但是根据this Answer,JPA 2.2支持 java.time 类型。

Hibernate也支持 java.time