为了账号安全,请及时绑定邮箱和手机立即绑定

如果应用程序使用除 MySQL 之外的其他时区,Hibernate 会保存/检索日期减去日期

如果应用程序使用除 MySQL 之外的其他时区,Hibernate 会保存/检索日期减去日期

弑天下 2021-09-03 14:14:59
我在 MACHINE_A 上的 tomcat 上启动了一个应用程序,时区为 GMT+3。我使用在 MACHINE_B 上启动的远程 MySQL 服务器,时区为 UTC。我们使用 spring-data-jpa 进行持久化。作为问题的一个例子,我将展示存储库:public interface MyRepository extends JpaRepository<MyInstance, Long> {    Optional<MyInstance> findByDate(LocalDate localDate);}如果我通过 localDate for 2018-09-06,我会得到日期所在的实体2018-09-05(前一天)在日志中我看到:2018-09-06 18:17:27.783 TRACE 13676 --- [nio-8080-exec-3] o.h.type.descriptor.sql.BasicBinder      : binding parameter [1] as [DATE] - [2018-09-06]我用谷歌搜索了很多这个问题,发现了几篇内容相同的文章(例如https://moelholm.com/2016/11/09/spring-boot-controlling-timezones-with-hibernate/)所以,我有以下几点application.yml:spring:  datasource:    url: jdbc:mysql://localhost:3306/MYDB?useUnicode=true&characterEncoding=utf8&useSSL=false&useLegacyDatetimeCode=false&serverTimezone=UTC    username: root    password: *****  jpa:    hibernate:      naming:        physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl    properties:      hibernate:        show_sql: true        use_sql_comments: true        format_sql: true        type: trace        jdbc:          time_zone: UTC但它没有帮助。我们使用以下连接器:<dependency>    <groupId>mysql</groupId>    <artifactId>mysql-connector-java</artifactId>    <version>8.0.12</version></dependency>我该如何解决我的问题?聚苯乙烯我尝试使用相同的时区运行两个应用程序。在这种情况下,一切都按预期进行。PS2我尝试使用 MySQL 驱动程序 6.0.6 版本,但它没有改变任何东西。
查看完整描述

3 回答

?
Qyouu

TA贡献1786条经验 获得超11个赞

我在为spring-boot使用hibernate. 我在这里使用的数据库是postgreSQL.


正如另一个答案正确指出的那样,您可以hibernate.jdbc.time_zone=UTC像描述一样设置属性。没关系这并没有解决我的问题,所以我不得不JVM在我的spring-boot应用程序主类中借助以下帮助设置默认时区:


@PostConstruct

public void init(){

    TimeZone.setDefault(TimeZone.getTimeZone("UTC"));   // It will set UTC timezone

    System.out.println("Spring boot application running in UTC timezone :"+new Date());   // It will print UTC timezone

}

这也应该可以解决您的问题。您可以在此处收集更多信息。


原因


我猜您的问题(检索日期 - 1 天)来自您的特定设置。如果您的应用程序在运行UTC和在GMT + 3它解决了一个提前数据库请求时间戳记,因为应用程序上下文(JVM和Hibernate负责这里)是UTC在数据库方面落后3小时。简单的例子:


2018-12-02 00:00:00 - 3 小时 = 2018-12-01 21:00:00


因为您只关注日期:2018-12-02- 3 小时 =2018-12-01


查看完整回答
反对 回复 2021-09-03
?
慕田峪7331174

TA贡献1828条经验 获得超13个赞

在 MySQL...

TIMESTAMP内部存储 UTC,但根据两个设置转换为/从服务器的时区。通过SHOW VARIABLES LIKE '%zone%'; 正确配置检查这些设置,读者可能会看到与作者不同的时间(基于 tz 设置)。

DATEDATETIME接受你给予的任何东西。客户端中的字符串与表中存储的内容之间没有 tz 转换。把它想象成一个存储时钟的图片。读者将看到作者所写的相同时间字符串。


查看完整回答
反对 回复 2021-09-03
  • 3 回答
  • 0 关注
  • 155 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信