如果应用程序使用另一个时区而不是MySQL,则Hibernate会保存/检索日期减去日期

gst*_*low 14 java mysql timezone hibernate spring-boot

我在MACHINE_A上使用时区GMT + 3在tomcat上启动了一个应用程序.

我使用带有时区UTC的MACHINE_B上启动的远程MySQL服务器.

我们使用spring-data-jpa来表示持久性.

作为问题的一个例子,我将展示存储库:

public interface MyRepository extends JpaRepository<MyInstance, Long> {
    Optional<MyInstance> findByDate(LocalDate localDate);
}
Run Code Online (Sandbox Code Playgroud)

如果我传递localDate 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]
Run Code Online (Sandbox Code Playgroud)

我用Google搜索这个问题有很多,发现了同样内容的几篇文章(例如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
Run Code Online (Sandbox Code Playgroud)

但它没有帮助.

我们使用以下连接器:

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.12</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)

我该如何解决我的问题?

PS

我试图用相同的时区运行这两个应用程序.在这种情况下,一切都按预期工作.

PS2

我试图使用MySQL驱动程序6.0.6版本但它没有改变任何东西.

Vla*_*cea 12

如果您LocalDate在Java中使用,则应使用DATEMySQL中的列.这样问题就解决了.

如果您使用LocalDateTime,请尝试在Spring Boot中设置如下属性:

spring.jpa.properties.hibernate.jdbc.time_zone=UTC
Run Code Online (Sandbox Code Playgroud)

有关更详细的说明,请查看此文章.您可以在我的高性能Java Persistence GitHub存储库中找到一个测试用例,它可以正常工作.


git*_*flo 6

我在为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
}
Run Code Online (Sandbox Code Playgroud)

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

原因

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

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

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