Java – hibernate + spring boot store date on UTC time zone troubles

datetimehibernatejavaspringspring-boot

I'm making some tests to define UTC as default time zone for my application. First of all I want my datetime values to be stored with the UTC one.

According to VLAD MIHALCEA (https://vladmihalcea.com/how-to-store-date-time-and-timestamps-in-utc-time-zone-with-jdbc-and-hibernate/) and https://moelholm.com/2016/11/09/spring-boot-controlling-timezones-with-hibernate/ I have set in my properties file:

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

For testing I'm using h2 database, I've created a sample entity with all java 8 dateTime Type.

In my liquibase config they are defined like this:

<column name="instant" type="timestamp"/>
<column name="local_date" type="date"/>
<column name="local_time" type="time"/>
<column name="offset_time" type="time"/>
<column name="local_date_time" type="timestamp"/>
<column name="offset_date_time" type="timestamp"/>
<column name="zoned_date_time" type="timestamp"/>

I think I'm using the good type for every fields. It's work for all fields except for "local_time" "offset_time" which are Time sql types not timestamp.

enter image description here

As you can see i added this row at 8:39am (Paris GMT+2) and timestamps have the good UTC value (6:38am).
BUT both "local_time" and "offset_time" have a strange value (7:39am).

I wonder why this behaviour, if some of you have an idea why my two time fields not store values correctly.

PS: version:

  • Hibernate: 5.2.17.Final
  • Spring boot: 2.0.4.RELEASE

My sample Entity use to insert data :

import javax.persistence.*;
import java.io.Serializable;
import java.time.*;
import java.util.Objects;

@Entity
@Table(name = "avdev_myData")
public class MyData implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
    @SequenceGenerator(name = "sequenceGenerator")
    private Long id;

    @Column(name = "name")
    private String name;

    @Column(name = "instant")
    private Instant instant;

    @Column(name = "local_date")
    private LocalDate localDate;

    @Column(name = "local_time")
    private LocalTime localTime;

    @Column(name = "offset_time")
    private OffsetTime offsetTime;

    @Column(name = "local_date_time")
    private LocalDateTime localDateTime;

    @Column(name = "offset_date_time")
    private OffsetDateTime offsetDateTime;

    @Column(name = "zoned_date_time")
    private ZonedDateTime zonedDateTime;

Best Answer

Have a try:

@SpringBootApplication
public class YourApplication {

    @PostConstruct
    void started() {
        // set JVM timezone as UTC
        TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
    }
}