deamon
deamon

Reputation: 92580

OffsetDateTime persisted by JPA differs by 2 hours

I have a JPA entity class with an OffsetDateTime field like this:

@Entity
class MyEntity(clock: Clock) {
    // ...
    val created: OffsetDateTime = OffsetDateTime.now(clock)
}

In a repository test I check that the date is corretly mapped:

assertThat(entity.created).isEqualTo(defaultDateTime)

If I compare the underlying Instant (and not also the offset) with OffsetDateTime#isEqual it works:

assertThat(entity.created.isEqual(defaultDateTime)).isTrue()

defaultDateTime and the clock are created with this code:

val defaultDateTime: OffsetDateTime =
    OffsetDateTime.of(2019, 6, 15, 11, 48, 59, 0, ZoneOffset.UTC)

fun createTestClock(dateTime: OffsetDateTime = defaultDateTime) = 
    Clock.fixed(dateTime.toInstant(), ZoneId.of("UTC"))

But if I run my test, the time differs by exactly 2 hours (what is the actual offset in my region, central europe). The PostgreSQL database returns GMT if I query the timezone with show timezone;.

The column data type is:

timestamp with time zone not null

Setting the respective Hibernate property doesn't help:

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

What is wrong?

Upvotes: 4

Views: 3177

Answers (1)

Tumo Masire
Tumo Masire

Reputation: 432

I believe that UTC and GMT have a (UTC) time offset of 0. Central Europe uses CET (Central European Time), which currently has an (UTC) offset of +2. This would explain the answer being off by 2hrs.

I would recommend maybe setting the default timezone in java (in your main application)

@PostConstruct
void started() {
  TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
}

and/or change the DB Timezone like

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

to

spring.jpa.properties.hibernate.jdbc.time_zone=CET;

I think the issue may be java using your default timezone on your machine. When it compares the Entity I believe it compares them as UTC strings, so they would match, but if you compare the offset, your local may be CET (+2) while the timestamp is UTC/GMT (+0)

This is one possibility, just my knowledge of Java and Postrges more than Spring.

Upvotes: 3

Related Questions