带有 MySql DB 的 Spring Boot JPA - 映射日期以错误的日期结束(休息 1 天)

Posted

技术标签:

【中文标题】带有 MySql DB 的 Spring Boot JPA - 映射日期以错误的日期结束(休息 1 天)【英文标题】:Spring boot JPA with MySql DB - mapping Dates ends in having wrong day (1 day off) 【发布时间】:2020-06-08 06:35:34 【问题描述】:

目前我在使用 Spring JPA 时遇到了一个奇怪的问题:每当我尝试将日期映射为仅日期时,它会将我想要保存的日期减去 1 天。例如。保存 2 月 1 日 --> 我的数据库中有 1 月 31 日。 只要我使用 DateTime,一切正常。 例子 : mysql时区设置为系统 系统在 UTC + 1 在连接 URL 中,serverTimeZone 设置为 UTC 并且 useLegacyDatetimeCode = true

@Entity
public class ZoneEntity

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    private Long id;

    @CreationTimestamp
    private LocalDateTime createDateTime;

    @CreationTimestamp
    private LocalDate createDate;

    @Temporal(value = TemporalType.TIMESTAMP)
    private Date temporalDate;

    private LocalDateTime localDateTime;

    private LocalDate localDate;

    @Column(columnDefinition = "DATE")
    private LocalDate localDateWithColumn;

    public ZoneEntity() 
        temporalDate = new Date();
        localDateTime = LocalDateTime.now();
        localDate = LocalDate.now();
        localDateWithColumn = LocalDate.now();
    

然后我会像这样保存一个新实体:

service.save(new ZoneEntity());

如果我今天(24.02.2020)执行此操作,我将得到以下结果

createDateTime : 24.02.2020 15:20:00  --> Correct (UTC)

createDate : 23.02.2020 --> day - -1

temporalDate : 24.02.2020 15:20:00 --> Correct (UTC)

localDate : 23.02.2020 --> day - 1

localDateTime : 24.02.2020 15:20:00 --> Correct (UTC)

localDateWithColumn : 23.02.2020 --> day - 1

所以我只保存日期,它以错误的日期结束。有人知道为什么会这样吗?

补充:

如果我查看休眠日志,问题似乎出在 MySQL 方面...

Hibernate: 
    insert 
    into
        zone_entity
        (create_date, create_date_time, local_date, local_date_time, local_date_with_column, temporal_date, id) 
    values
        (?, ?, ?, ?, ?, ?, ?)
2020-02-24 16:42:25.371 TRACE 19628 --- [nio-8080-exec-2] o.h.type.descriptor.sql.BasicBinder      : binding parameter [1] as [DATE] - [2020-02-24]
2020-02-24 16:42:25.374 TRACE 19628 --- [nio-8080-exec-2] o.h.type.descriptor.sql.BasicBinder      : binding parameter [2] as [TIMESTAMP] - [2020-02-24T16:42:25.365036900]
2020-02-24 16:42:25.375 TRACE 19628 --- [nio-8080-exec-2] o.h.type.descriptor.sql.BasicBinder      : binding parameter [3] as [DATE] - [2020-02-24]
2020-02-24 16:42:25.375 TRACE 19628 --- [nio-8080-exec-2] o.h.type.descriptor.sql.BasicBinder      : binding parameter [4] as [TIMESTAMP] - [2020-02-24T16:42:25.302181]
2020-02-24 16:42:25.375 TRACE 19628 --- [nio-8080-exec-2] o.h.type.descriptor.sql.BasicBinder      : binding parameter [5] as [DATE] - [2020-02-24]
2020-02-24 16:42:25.376 TRACE 19628 --- [nio-8080-exec-2] o.h.type.descriptor.sql.BasicBinder      : binding parameter [6] as [TIMESTAMP] - [Mon Feb 24 16:42:25 CET 2020]
2020-02-24 16:42:25.376 TRACE 19628 --- [nio-8080-exec-2] o.h.type.descriptor.sql.BasicBinder      : binding parameter [7] as [BIGINT] - [294]

补充:如果我尝试通过 MySQL 工作台插入以下值(如 Hibernate 中的参数所示),一切正常(省略时间戳以使其更短一些)。

insert 
    into
        zone_entity
        (create_date, create_date_time, local_date, local_date_time, local_date_with_column,id) 
    values
        ('2020-02-24', '2020-02-24T22:03:13.842324', '2020-02-24', '2020-02-24T22:03:13.842324', '2020-02-24',99);

添加: 我现在将 DB URL 中的时区更改为 Europe/London --> 一切正常。更改为 UTC 或欧洲/伦敦 --> 两者都不起作用!

spring.datasource.url = jdbc:mysql://localhost:3306/myDatabase?serverTimezone=Europe/Berlin&useLegacyDatetimeCode=false

提前非常感谢!

亲切的问候

乔恩

【问题讨论】:

正好是 1 天还是几个小时?据我所知,它将时间转换为 UTC。 好像是1天。所以我的系统时间是 UTC+1,MySQL 在系统上,但我发送的是 UTC。所以所有时间都是正确的。仅当我发送“仅日期”时,它是在前 1 天 - 从我的 POV 来看,这似乎与时区无关,因为当地时间距 UTC 仅 1 小时。此外,当我执行与今天下午相同的插入操作时,所有日期字段中仍然有 23.02.2020。 SHOW VARIABLES LIKE '%zone%'; 另外,我认为 MySQL 不喜欢中间的“T”。 这可能会有所帮助:***.com/questions/41938999/… 【参考方案1】:

你试过spring yml中的以下参数吗?

spring:
  jpa:
    properties:
       hibernate.jdbc.time_zone: Europe/Berlin

【讨论】:

嗨 Suraj,我在此期间做了一个解决方法,我保存为日期/时间并仅换行到日期。但我会试一试,只需要几天时间,直到我重新开始。谢谢 !乔恩

以上是关于带有 MySql DB 的 Spring Boot JPA - 映射日期以错误的日期结束(休息 1 天)的主要内容,如果未能解决你的问题,请参考以下文章

带有 DB 的 Spring Boot 应用程序 - 使用 @DirtiesContext 重新创建上下文后测试类失败

Spring boot - 尝试从 mySQL DB 验证用户 - 需要授予权限的文本表示

带有 Spring Boot 应用程序的 docker secret 在 docker swarm 模式 /run/secrets 下不起作用

SQLException:在 Spring Boot 中访问被拒绝

Spring boot(带有 jpa 的 mysql):没有名为“entityManagerFactory”的 bean 可用

使用带有 LIKE 的 mysql 本机查询的 spring boot 搜索返回空