Postgres中没有时区默认CURRENT_TIMESTAMP的字段TIMESTAMP的JPA模型类?
Posted
技术标签:
【中文标题】Postgres中没有时区默认CURRENT_TIMESTAMP的字段TIMESTAMP的JPA模型类?【英文标题】:JPA Model Class for field TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP in Postgres? 【发布时间】:2019-11-18 03:43:31 【问题描述】:我在 Postgres 中使用了 Java 8 和 Postgres-11 和 Spring Boot 2.1.6.RELEASE。我已经使用了this question 和this question,但我真的很想使用 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】:类型错误
LocalDateTime
在这里是错误的类型。正如其 Javadoc 中所解释的那样,该类不能代表片刻。
该类故意没有时区或从 UTC 偏移的概念。所以它代表一个日期和一天中的时间,例如“2019 年 1 月 23 日中午”,但不知道是东京、巴黎还是蒙特利尔的中午,例如,三个非常不同的时刻相隔几个小时。所以这种类型适用于标准 SQL 类型TIMESTAMP WITHOUT TIME ZONE
- without,而不是 with。
更多讨论请见:What's the difference between Instant and LocalDateTime?
正确的类型
对于标准 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(零偏移)调整为特定地区(时区)人们使用的挂钟时间。
ZoneId z = ZoneId.of( "Asia/Tokyo" ;
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;
JPA
我不使用 JPA,我更喜欢保持简单。
但是根据this Answer,JPA 2.2 支持 java.time 类型。
Hibernate 也支持 java.time。
【讨论】:
以上是关于Postgres中没有时区默认CURRENT_TIMESTAMP的字段TIMESTAMP的JPA模型类?的主要内容,如果未能解决你的问题,请参考以下文章
使用 node-postgres 在 utc 中获取 Postgres“没有时区的时间戳”
将 Postgres 中没有时区的 DateTime 字段从中欧时间转换为 UTC
Rails 和 Postgres:迁移到 change_colomn 时出现错误“无法强制转换为没有时区的时间戳”
使用 Spring Data 的 postgres 中的时间戳出错:列 $COLUMN_NAME 是没有时区的时间戳类型,但表达式是 bytea 类型