我有一个应用程序在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版本,但它没有改变任何事情。
8条答案
按热度按时间htrmnn0y1#
spring.jpa.properties.hibernate.jdbc.time_zone=UTC
当您在使用时区日期时,会使用它,但从您的日志来看,您似乎没有通过时区:绑定参数[1]为[date]-[2018-09-06]
尝试删除远程属性:
spring.jpa.properties.hibernate.jdbc.time_zone=UTC
1yjd4xko2#
在8.0.22之前的mysql连接器中有一个bug,请参阅SpringDataQueryforLocalDate返回错误条目-减去一天
wz1wpwve3#
如果你用的是
LocalDate
在java中,应该使用DATE
mysql中的列。这样问题就解决了。如果你使用
LocalDateTime
,请尝试在spring boot中设置如下属性:要获得更详细的解释,请查看本文。您可以在我的高性能java持久性github存储库中找到一个测试用例,它演示了这个设置如何与mysql一起工作。
wgx48brx4#
我已经按照答案里的指示做了每件事,比如
添加spring.jpa.properties.hibernate.jdbc.time\u zone=美国/圣保罗
设置默认时区:
TimeZone.setDefault(TimeZone.getTimeZone("America/Sao_Paulo"))
但直到我在jdbc url中添加参数servertimezone=america/saoèpaulo:现在一切正常!
syqv5f0l5#
在mysql中。。。
TIMESTAMP
内部存储utc,但基于两种设置转换服务器时区。通过检查这些设置SHOW VARIABLES LIKE '%zone%';
如果配置正确,读卡器可能会看到与写卡器不同的时间(基于tz设置)。DATE
以及DATETIME
你给什么就拿什么。客户机中的字符串和表中存储的字符串之间没有转换。把它想象成一个存储时钟图片的过程。读者将看到与作者编写的相同的时间字符串。qvtsj1bj6#
如果将以下解析添加到hql查询中,它将返回一个没有任何时区格式或时间的日期。这是一个快速解决你的问题。
gdrx4gfi7#
在为一个应用程序创建一些集成测试时,我遇到了类似的问题
spring-boot
应用程序使用hibernate
. 我在这里使用的数据库是postgreSQL
.正如另一个正确的答案所指出的,您可以设置
hibernate.jdbc.time_zone=UTC
描述的属性。不管怎样,这并不能解决我的问题,所以我必须设置JVM
默认时区spring-boot
应用程序主类:这也能解决你的问题。你可以在这里收集更多的信息。
原因
我猜你的问题(检索日期-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
lrl1mhuk8#
理想情况下,您的两个服务器应该在同一时区,首选的服务器应该在utc时区。并向用户显示其所在时区的正确时间;您可以在浏览器本身中解析它。从数据库检索数据时;使用utc时间。这样,在从数据库获取数据时就不会出现问题