hibernate保存/检索日期减去天

wtlkbnrh  于 2021-06-20  发布在  Mysql
关注(0)|答案(8)|浏览(333)

我有一个应用程序在tomcat上的机器上启动,时区是gmt+3。
我使用的是在时区为utc的机器\u b上启动的远程mysql服务器。
我们使用spring数据jpa进行持久化。
作为问题的一个例子,我将展示存储库:

public interface MyRepository extends JpaRepository<MyInstance, Long> {
    Optional<MyInstance> findByDate(LocalDate localDate);
}

如果我把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]

我在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

但没用。
我们使用以下连接器:

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.12</version>
</dependency>

我怎样才能解决我的问题?

p、 s。

我尝试在同一时区运行两个应用程序。在这种情况下,一切正常。

p、 第2节

我尝试使用mysql驱动程序6.0.6版本,但它没有改变任何事情。

htrmnn0y

htrmnn0y1#

spring.jpa.properties.hibernate.jdbc.time_zone=UTC 当您在使用时区日期时,会使用它,但从您的日志来看,您似乎没有通过时区:
绑定参数[1]为[date]-[2018-09-06]
尝试删除远程属性: spring.jpa.properties.hibernate.jdbc.time_zone=UTC

1yjd4xko

1yjd4xko2#

在8.0.22之前的mysql连接器中有一个bug,请参阅SpringDataQueryforLocalDate返回错误条目-减去一天

wz1wpwve

wz1wpwve3#

如果你用的是 LocalDate 在java中,应该使用 DATE mysql中的列。这样问题就解决了。
如果你使用 LocalDateTime ,请尝试在spring boot中设置如下属性:

spring.jpa.properties.hibernate.jdbc.time_zone=UTC

要获得更详细的解释,请查看本文。您可以在我的高性能java持久性github存储库中找到一个测试用例,它演示了这个设置如何与mysql一起工作。

wgx48brx

wgx48brx4#

我已经按照答案里的指示做了每件事,比如
添加spring.jpa.properties.hibernate.jdbc.time\u zone=美国/圣保罗
设置默认时区: TimeZone.setDefault(TimeZone.getTimeZone("America/Sao_Paulo")) 但直到我在jdbc url中添加参数servertimezone=america/saoèpaulo:

jdbc:mysql://localhost:3306/aurorabuzz-test?serverTimezone=America/Sao_Paulo

现在一切正常!

syqv5f0l

syqv5f0l5#

在mysql中。。。 TIMESTAMP 内部存储utc,但基于两种设置转换服务器时区。通过检查这些设置 SHOW VARIABLES LIKE '%zone%'; 如果配置正确,读卡器可能会看到与写卡器不同的时间(基于tz设置)。 DATE 以及 DATETIME 你给什么就拿什么。客户机中的字符串和表中存储的字符串之间没有转换。把它想象成一个存储时钟图片的过程。读者将看到与作者编写的相同的时间字符串。

qvtsj1bj

qvtsj1bj6#

如果将以下解析添加到hql查询中,它将返回一个没有任何时区格式或时间的日期。这是一个快速解决你的问题。

select DATE_FORMAT(date,'%Y-%m-%d') from Entity
gdrx4gfi

gdrx4gfi7#

在为一个应用程序创建一些集成测试时,我遇到了类似的问题 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

lrl1mhuk

lrl1mhuk8#

理想情况下,您的两个服务器应该在同一时区,首选的服务器应该在utc时区。并向用户显示其所在时区的正确时间;您可以在浏览器本身中解析它。从数据库检索数据时;使用utc时间。这样,在从数据库获取数据时就不会出现问题

相关问题