Search code examples
javaspring-bootspring-data-jpazoneddatetime

After Spring boot 3.2.x upgrade , ZoneddateTime is getting persisted in DB always with UTC format


Working scenario:

Service-A : with Java 8 , Spring boot 2.7.x

  • Setting the ZoneddateTime ("America/New_York") in java object and adding it in RabbitMQ queue.

Service-B : with Java 8 , Spring boot 2.7.9

  • Receives the ZoneddateTime from Queue and persisting it in MySql DB.
  • ZoneddateTime is persisted in EST/EDT format as expected.

Mysql DB:

  • Result of the query (SELECT @@system_time_zone;) is EDT.
  • data type column in MySQL store the ZoneddateTime is - datetime

Issue:

After upgrading the Service-B (service which persist the date time in DB) to Java 17 & Spring boot 3.2.9. ZoneddateTime is getting persisted UTC format (EDT + 4 hrs)

Debugging :

  1. I tried to convert the time to EDT/EST and then persist in DB. But still its storing it in UTC format only.
final ZonedDateTime inboundTimeEST = inboundTime.withZoneSameInstant("America/New_York");
obj.setRequestTime(inboundTimeEST);
obj.setMyJson(XXX().getBytes()); // Json in bytes
logsRepository.save(obj);

obj is from our entity class. Data type of the request time is ZonedDateTime. imported these two packages import jakarta.persistence.*;import java.time.ZonedDateTime; in our class

  1. I downgraded the spring boot version to 2.7.9 with Java 17. the ZoneddateTime is persisted in EST/EDT format as expected. So the issue is not due to the Java upgrade i guess.

Any recommendations or suggestion to fix this issue or to debug it further? I am expecting the datetime should be in EDT/EST format.


Solution

  • This issue is due to the change in Hibernate 6.x behavior.

    Spring Boot 2.x uses Hibernate 5.x , but the Spring Boot 3.x uses Hibernate 6.x.

    In Hibernate 5, time zones were not stored, but normalized to the time zone set in hibernate.jdbc.time_zone / JVM time zone by default. But in Hibernate 6.x, date/time values are normalized to UTC.

    More details are available in the Hibernate Migration guide

    So, Setting the configuration property hibernate.timezone.default_storage to NORMALIZE reverts to the Hibernate 5’s behavior.