Postgres 中字段 TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP 的 JPA 模型 Class?
JPA Model Class for field TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP in Postgres?
我在 Postgres 中低于 Table 并使用 Java 8 和 Postgres-11 Spring Boot 2.1.6.RELEASE。我已经通过 this question and this question,但我真的想使用 Java 8 日期 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
);
我创建了如下模型 class,但与我需要的不匹配。
@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;
}
类型错误
LocalDateTime
是这里的错误类型。正如其 Java 文档中所解释的那样,class 不能代表一个时刻。
那个class故意没有时区的概念或者offset-from-UTC。所以它代表一个日期和一个time-of-day比如“2019年1月23日中午”,但不知道那是东京、巴黎还是蒙特利尔的中午,举个例子,三个截然不同的时刻相隔几个小时。所以这个类型适用于标准 SQL 类型 TIMESTAMP WITHOUT TIME ZONE
– without,而不是 with.
有关更多讨论,请参阅:
正确的类型
对于标准 SQL 类型 TIMESTAMP WITH TIME ZONE
,您应该使用 Java 类型 Instant
、OffsetDateTime
或 ZonedDateTime
。在这三个中,JDBC 4.2 只需要对第二个 OffsetDateTime
的支持。
检索。
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
从 Postgres 检索的值将始终采用 UTC。 SQL 标准未指定此行为,因此数据库各不相同。在 Postgres 中,发送到 TIMESTAMP WITH TIME ZONE
类型字段的任何值都将调整为 UTC。检索到的值采用 UTC。
存储。
myPreparedStatement.setObject( … , odt ) ;
从 UTC(零偏移量)调整为特定地区(时区)人们使用的 wall-clock 时间。
ZoneId z = ZoneId.of( "Asia/Tokyo" ;
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;
JPA
我不使用 JPA,更喜欢保持简单。
但是根据 this Answer,JPA 2.2 支持 java.time 类型。
Hibernate 也支持 java.time。
我在 Postgres 中低于 Table 并使用 Java 8 和 Postgres-11 Spring Boot 2.1.6.RELEASE。我已经通过 this question and this question,但我真的想使用 Java 8 日期 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
);
我创建了如下模型 class,但与我需要的不匹配。
@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;
}
类型错误
LocalDateTime
是这里的错误类型。正如其 Java 文档中所解释的那样,class 不能代表一个时刻。
那个class故意没有时区的概念或者offset-from-UTC。所以它代表一个日期和一个time-of-day比如“2019年1月23日中午”,但不知道那是东京、巴黎还是蒙特利尔的中午,举个例子,三个截然不同的时刻相隔几个小时。所以这个类型适用于标准 SQL 类型 TIMESTAMP WITHOUT TIME ZONE
– without,而不是 with.
有关更多讨论,请参阅:
正确的类型
对于标准 SQL 类型 TIMESTAMP WITH TIME ZONE
,您应该使用 Java 类型 Instant
、OffsetDateTime
或 ZonedDateTime
。在这三个中,JDBC 4.2 只需要对第二个 OffsetDateTime
的支持。
检索。
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
从 Postgres 检索的值将始终采用 UTC。 SQL 标准未指定此行为,因此数据库各不相同。在 Postgres 中,发送到 TIMESTAMP WITH TIME ZONE
类型字段的任何值都将调整为 UTC。检索到的值采用 UTC。
存储。
myPreparedStatement.setObject( … , odt ) ;
从 UTC(零偏移量)调整为特定地区(时区)人们使用的 wall-clock 时间。
ZoneId z = ZoneId.of( "Asia/Tokyo" ;
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;
JPA
我不使用 JPA,更喜欢保持简单。
但是根据 this Answer,JPA 2.2 支持 java.time 类型。
Hibernate 也支持 java.time。