Hibernate 5 doesn't handle LocalDate properly
Asked Answered
C

1

6

We're migrating our Hibernate (5.0.2) code to Java 8, which also involves conversion from java.util.Date to java.time.LocalDate (to solve issues related to date handling in Java 7). One of the problems I've run into is how Hibernate handles a special value we're using as a "zero date", which is 0001-01-01.

The property is declared as follows:

@NotNull
@Column(name = "START_DATE", nullable = false)
private LocalDate startDate;

The value is stored in the database as 0001-01-01, however when it's loaded by Hibernate it suddenly turns to 0000-12-29. I assume this happens because Hibernate uses Gregorian calendar by default, and since this date is before it was introduced, some conversion is used.

Is there any way to configure Hibernate to disable this behaviour (apart from implementing a special property writer)?

Calzada answered 10/12, 2015 at 16:24 Comment(2)
The bug ( hibernate.atlassian.net/browse/HHH-10371 ) was fixed in Hibernate 5.0.6 ( in.relation.to/2015/12/16/hibernate-orm-506-final-release ).Stere
@engineer It is fixed indeed, however we can't make use of it since there's no compatible version of hibernate-validator, whose latest version in the 5.0.x family was 5.0.3, and that one refuses to work with 5.0.6 hibernate-core. Any idea why the version is so far behind / when it'll be fixed?Calzada
A
3

It is a bug indeed. I replicated it in the following test. I'll open a bug report for it.

If I use LocalDate:

@Entity(name = "LocalDateEvent")
public class LocalDateEvent {

    @Id
    private Long id;

    @NotNull
    @Column(name = "START_DATE", nullable = false)
    private LocalDate startDate;
}

and run this test:

doInJPA(entityManager -> {
    LocalDateEvent event = new LocalDateEvent();
    event.id = 1L;
    event.startDate = LocalDate.of(1, 1, 1);
    entityManager.persist(event);
});

doInJPA(entityManager -> {
    LocalDateEvent event = entityManager.find(LocalDateEvent.class, 1L);
    assertEquals(LocalDate.of(1, 1, 1), event.startDate);
});

I get:

java.lang.AssertionError: expected:<0001-01-01> but was:<0000-12-29>

The Jira issue is here.

It doesn't work for OffsetDateTime either:

@Entity(name = "OffsetDateTimeEvent")
public static class OffsetDateTimeEvent {

    @Id
    private Long id;

    @NotNull
    @Column(name = "START_DATE", nullable = false)
    private OffsetDateTime startDate;
}

and running this test:

doInJPA(entityManager -> {
    OffsetDateTimeEvent event = new OffsetDateTimeEvent();
    event.id = 1L;
    event.startDate = OffsetDateTime.of(1, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC);
    entityManager.persist(event);
});

doInJPA(entityManager -> {
    OffsetDateTimeEvent event = entityManager.find(OffsetDateTimeEvent.class, 1L);
    assertEquals(OffsetDateTime.of(1, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC), event.startDate);
});

Throws:

java.lang.AssertionError: expected:<0001-01-01T00:00Z> but was:<0001-01-01T01:34:52+01:34:52>

The Jira issue for this is here.

Armalda answered 11/12, 2015 at 8:59 Comment(1)
Once you've filed a bug report, could you come back and leave a link to it here? Thanks!Calzada

© 2022 - 2024 — McMap. All rights reserved.