我在 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;
}
最佳答案
类型错误
LocalDateTime
这里的类型是错误的。正如 Javadoc 中所解释的,该类不能代表一个时刻。
该类故意没有时区或与 UTC 的偏移量的概念。因此它代表一个日期和一天中的时间,例如“2019 年 1 月 23 日中午”,但不知道那是东京、巴黎还是蒙特利尔的中午,例如,三个截然不同的时刻相隔几个小时。因此,此类型适用于标准 SQL 类型TIMESTAMP WITHOUT TIME ZONE
- 没有,而不是有。
更多讨论,请参阅: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。
关于java - Postgres 中字段 TIMESTAMP NOT TIME ZONE DEFAULT CURRENT_TIMESTAMP 的 JPA 模型类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56938079/