spring.jpa.properties.hibernate.jdbc.time_zone应用于写入,但不应用于读取?

问题描述 投票:0回答:1

我正在使用:

  • spring boot 2.0.4.RELEASE
  • spring-data-jpa 2.0.9.RELEASE
  • 休眠核心5.2.17.Final
  • hibernate-jpa-2.1-api 1.0.0.Final
  • postgres jdbc驱动程序42.2.9

我有以下实体:

@Entity
@EntityListeners(AuditingEntityListener.class)
public class MyEntity implements Serializable
{
    @Column(nullable = false, updatable = false)
    @CreatedDate
    private LocalDateTime createdDate;

    @Column(nullable = false)
    @LastModifiedDate
    private LocalDateTime lastModifiedDate;

    public LocalDateTime getCreatedDate()
    {
        return createdDate;
    }

    public LocalDateTime getLastModifiedDate()
    {
        return lastModifiedDate;
    }
}

以及以下在application.yaml中设置的属性:

spring:
  jpa:
    properties:
      hibernate:
        jdbc:
          time_zone: UTC

无论JVM时区/默认时区是什么,我都想以UTC保存并返回时间戳。

出于测试目的,我已将应用程序代码的时区设置为US/Hawaii

TimeZone.setDefault(TimeZone.getTimeZone("US/Hawaii"));

当我保存实体时,已使用UTC时间戳将其正确写入数据库:

[16:43:04.636Z #4c5.042 TRACE -            -   ] o.h.t.d.sql.BasicBinder: binding parameter [1] as [TIMESTAMP] - [2020-03-02T06:43:04.581]
[16:43:04.645Z #4c5.042 TRACE -            -   ] o.h.t.d.sql.BasicBinder: binding parameter [2] as [TIMESTAMP] - [2020-03-02T06:43:04.581]
[16:43:04.649Z #4c5.042 TRACE -            -   ] o.h.r.j.i.ResourceRegistryStandardImpl: Closing prepared statement [HikariProxyPreparedStatement@336047848 wrapping insert into myentity (createdDate, lastModifiedDate) values ('2020-03-02 16:43:04.581+00', '2020-03-02 16:43:04.581+00')]

但是,当我再次读回它时,它又回到了我在应用程序代码中设置的默认时区:US/Hawaii,而不是UTC

[16:43:04.692Z #4c5.043 TRACE -            -   ] o.h.t.d.sql.BasicExtractor: extracted value ([createdD4_0_0_] : [TIMESTAMP]) - [2020-03-02T06:43:04.581]
[16:43:04.692Z #4c5.043 TRACE -            -   ] o.h.t.d.sql.BasicExtractor: extracted value ([lastModi5_0_0_] : [TIMESTAMP]) - [2020-03-02T06:43:04.581]
[16:43:04.695Z #4c5.043 TRACE -            -   ] o.h.l.p.e.p.i.ResultSetProcessorImpl: Done processing result set (1 rows)
[16:43:04.696Z #4c5.043 TRACE -            -   ] o.h.l.p.e.p.i.AbstractRowReader: Total objects hydrated: 1
[16:43:04.696Z #4c5.043 TRACE -            -   ] o.h.l.p.e.p.i.ResultSetProcessingContextImpl: Skipping create subselects because there are fewer than 2 results, so query by key is more efficient.
[16:43:04.696Z #4c5.043 TRACE -            -   ] o.h.r.j.i.ResourceRegistryStandardImpl: Releasing result set [HikariProxyResultSet@622126582 wrapping org.postgresql.jdbc.PgResultSet@3f0764b8]
[16:43:04.696Z #4c5.043 TRACE -            -   ] o.h.r.j.i.ResourceRegistryStandardImpl: Closing result set [HikariProxyResultSet@622126582 wrapping org.postgresql.jdbc.PgResultSet@3f0764b8]
[16:43:04.696Z #4c5.043 TRACE -            -   ] o.h.r.j.i.ResourceRegistryStandardImpl: Releasing statement [HikariProxyPreparedStatement@1612081040 wrapping select myentity0_.createdDate as createdD4_0_0_, myentity0_.lastModifiedDate as lastModi5_0_0_, where myentity0_.fieldName='a-field-name' and myentity0_.id='KQTqSh7cQW' and myentity0_.tenantId='a-tenant-id']

我曾尝试将serverTimezone=UTC&useLegacyDatetimeCode=false添加到我的JDBC URL中,但没有区别。

可能相关:https://hibernate.atlassian.net/browse/HHH-13417

非常感谢您的帮助。

更新

基于@midhun mathew的回答,我发现足以控制设置应用程序代码中的日期来解决此问题:

myEntity.setCreatedDate(LocalDateTime.ofInstant(Instant.now(), ZoneOffset.UTC))
public void setCreatedDate(LocalDateTime createdAt) 
{ 
  this.createdAt = createdAt; 
}

现在,当写入数据库时​​,日期被“绑定”并插入为UTC(与原始日期中被“绑定”的原始帖子为US\Hawaii,但插入为UTC):] >

[10:10:21.475Z #065.042 TRACE -            -   ] o.h.t.d.sql.BasicBinder: binding parameter [1] as [TIMESTAMP] - [2020-03-03T10:10:17.400]
[10:10:21.476Z #065.042 TRACE -            -   ] o.h.t.d.sql.BasicBinder: binding parameter [2] as [TIMESTAMP] - [2020-03-03T10:10:17.400]
[HikariProxyPreparedStatement@860888944 wrapping insert into tag (createdDate, lastModifiedDate, deleted, irrevocable, scope, version, fieldName, id, tenantId) values ('2020-03-03 10:10:17.4-10', '2020-03-03 10:10:17.4-10', 'FALSE', 'FALSE', 'DOCUMENT', 0, 'a-field-name', 'BpqLX7mDR4', 'a-tenant-id')]
[10:10:21.479Z #065.042 TRACE -            -   ] 

并且从数据库读取实体时,日期不再读取为US/Hawaii,而是UTC

[10:10:24.527Z #065.043 TRACE -            -   ] o.h.t.d.sql.BasicExtractor: extracted value ([createdD4_0_0_] : [TIMESTAMP]) - [2020-03-03T10:10:17.400]
[10:10:24.527Z #065.043 TRACE -            -   ] o.h.t.d.sql.BasicExtractor: extracted value ([lastModi5_0_0_] : [TIMESTAMP]) - [2020-03-03T10:10:17.400]

我正在使用:spring boot 2.0.4.RELEASE spring-data-jpa 2.0.9.RELEASE hibernate-core 5.2.17.Final hibernate-jpa-2.1-api 1.0.0.Final postgres jdbc driver 42.2.9我有以下实体:@Entity @ ...

java postgresql hibernate jpa jdbc
1个回答
1
投票

我也遇到过同样的问题。我的数据库时区为UTC,而应用程序时区为新加坡。我通过使实体和表都具有UTC日期来解决此问题,因此它们之间无需进行任何转换。然后,我在getter和setter中的代码中的时间戳之间进行了转换。

© www.soinside.com 2019 - 2024. All rights reserved.