问题描述
我在Postgres中的表格下方,并在Spring Boot 2.1.6.RELEASE 中使用 Java 8和Postgres-11 。我已经浏览了链接:
错误类型
LocalDateTime
是错误的类型。该类不能代表片刻,如其Javadoc中所述。
该类故意没有时区或从UTC偏移的概念。因此它代表一个日期和时间,例如 2019年1月23日中午,但不知道在东京,巴黎或蒙特利尔是否是中午,例如,三个非常不同的时刻相距几个小时。因此,此类型适用于标准SQL类型没有时区的时间戳
– 没有,而不是 with 。
有关更多讨论,请参见:
右类型
对于标准SQL类型 TIMESTAMP WITH时区
,您应该使用Java类型即时
, 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,而是希望保持简单。
但是根据,JPA 2.2支持 java.time 类型。
Hibernate也支持 java .time 。
I've below Table in Postgres and using Java 8 and Postgres-11 with Spring Boot 2.1.6.RELEASE. I already went through the link: How to map timestamp column to JPA type? and Hibernate creates column without name when using "default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP", but I really wanted to use Java 8 Date API and not Java 7.
CREATE TABLE note(
note_id serial PRIMARY KEY,
message varchar(255) NOT NULL,
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);
I've created model class like below, but doesn't match with what I need. Any help?
@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;
}
Wrong type
LocalDateTime
is the wrong type here. That class cannot represent a moment, as explained in its Javadoc.
That class purposely has no concept of time zone or offset-from-UTC. So it represents a date and a time-of-day such as "noon on the 23rd of January 2019", but don’t know if that is noon in Tokyo, Paris, or Montréal, for a example, three very different moments that are several hours apart. So this type is appropriate for standard SQL type TIMESTAMP WITHOUT TIME ZONE
– without, not with.
For more discussion, see: What's the difference between Instant and LocalDateTime?
Right type
For standard SQL type TIMESTAMP WITH TIME ZONE
, you should be using the Java types Instant
, OffsetDateTime
, or ZonedDateTime
. Of those three, JDBC 4.2 requires support only for the second, OffsetDateTime
.
Retrieval.
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
The value retrieved from Postgres will always be in UTC. The SQL standard does not specify this behavior, so databases vary. In Postgres any value sent to a field of type TIMESTAMP WITH TIME ZONE
is adjusted into UTC. Retrieved values are in UTC.
Storing.
myPreparedStatement.setObject( … , odt ) ;
Adjust from UTC (offset of zero) to the wall-clock time used by the people of a particular region (a time zone).
ZoneId z = ZoneId.of( "Asia/Tokyo" ;
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;
JPA
I don’t use JPA, preferring to keep things simple.
But according to this Answer, JPA 2.2 support the java.time types.
Hibernate as well supports java.time.
这篇关于Postgres中没有时区DEFAULT CURRENT_TIMESTAMP的字段TIMESTAMP的JPA模型类?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!