Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hibernate 5 doesn't handle LocalDate properly

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)?

like image 412
yktoo Avatar asked Dec 10 '15 16:12

yktoo


1 Answers

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.

like image 74
Vlad Mihalcea Avatar answered Oct 19 '22 00:10

Vlad Mihalcea