Add support for Java 8 date and time types (JSR-310)
Description
is followed up by
Activity
Mirko Mittmann April 13, 2015 at 12:56 PM
Hi,
i'm new to this, but i have something for the "HHH000072: Duplicate joins for class:".
I've tested the new version. In the class "org.hibernate.boot.internal.InFlightMetadataCollectorImpl" was this message thrown,
after using following code:
MetadataSources metadataSources = new MetadataSources(standardServiceRegistry).addAnnotatedClass(....class).addAnnotatedClass(....class).addAnnotatedClass(....class);
MetadataBuilder metadataBuilder = metadataSources.getMetadataBuilder();
Metadata metadata = metadataBuilder.build();
After "metadataBuilder.build()" my 3 classes from addAnnotatedClass where duplicated. I saw this in the method "imports" from "MetadataImpl".
Hope it could help for resolving.
PS: If i had made a mistake for posting this here, please moved or delete it.
JB Nizet March 26, 2015 at 5:31 PMEdited
By Spring integration, I mean that I use spring-orm and spring-data-jpa in the app to create the EMFactory, handle declarative transactions, discover entities by classpath scanning, etc., and it worked fine. I wouldn't have been surprised, given the major version change, if Spring had a problem with the new version. It appeared that it didn't have any. That was not possible when switching from hibernate 3 to hibernate 4, and Spring had to rewrite many classes for hibernate 4 support.
I indeed let Hibernate set everything up. I just changed the hibernate version number in my gradle dependencies, added the hibernate-java8 dependency, removed the jadira dependency, and everything went fine. A typical mapped Instant field looks like this:
private Instant registrationDate;
Regarding the last question, it's a tough one. I made that choice based on this SO answer and the linked blog post.
Given that JDBC uses the default timezone by default when setting a timestamp (unless you use the method with an additional Calendar argument, using a timestamptz is much safer, because it pays attention to the timezone, meaning that no conversion needs to be done at all, and no Calendar needs to be passed to have the correct value stored in UTC.
numéro6 March 26, 2015 at 5:10 PM
@Steve Ebersole Using Hibernate 5 snapshot breaks ToPIA (jenkins build), I won't be able to provide a feedback soon (too bad!) We have to solve all those compatibility break first.
Steve Ebersole March 26, 2015 at 4:56 PM
@JB Nizet Awesome, thanks for trying it out! I have noticed that occasionally too wrt HHH000072, but have been so heads down trying to get ready for the 5.0.0 Beta release that I have not yet had time to look closer. I will get to it.
@JB Nizet Out of curiosity, what is "Spring integration"?
@JB Nizet Did you just let Hibernate set everything up and let it pick the types based on the attribute's Java type? That's the main thing here. Once that all happens, schema generation and other stuff will just flow. Although I will say that for schema export etc Hibernate does not generally use "with timezone" variants of date/time. Which brings me too...
There is a discussion on the dev mailing list right now wrt these types and handling timezones. IMO we really ought to be leveraging the power of these new classes and converting everything to UTC (if not already in UTC) for storing. And then reading back in UTC. My personal belief is that "this idea of trying to store and handle dates in different timezones is silly, and more importantly that it is asking for trouble". If anyone has strong opinions, they might want to chime in on that email thread.
JB Nizet March 26, 2015 at 4:18 PM
I just tested it on quizzie.io, which currently uses jadira: all tests pass, and the app runs smoothly.
Some notes and caveats:
the only java.time type used in the entities is java.time.Instant
the database schema is not generated by Hibernate, so I didn't test schema generation.
database used is PostgreSQL 9.3, column type is timestamptz
Spring integration works fine
unrelated: I get a warning for *every* entity that I didn't get with Hibernate 4, which is not very clear and seems like a false positive: `WARN o.h.b.i.InFlightMetadataCollectorImpl - HHH000072: Duplicate joins for class: ...`. Note that I get this warning even for entities that have no association at all with any other entity.
Implement support for the new Java 8 temporal Java types (JSR 310).
The initial implementation defines the following Types:
org.hibernate.type.DurationType
- Maps ajava.time.Duration
to a SQL BIGINT (Long) representing the duration-in-nanoseconds.org.hibernate.type.InstantType
- Maps ajava.time.Instant
to a SQL TIMESTAMPorg.hibernate.type.LocalDateTimeType
- Maps ajava.time.LocalDateTime
to a SQL TIMESTAMPorg.hibernate.type.LocalDateType
- Maps ajava.time.LocalDate
to a SQL DATEorg.hibernate.type.LocalTimeType
- Maps ajava.time.LocalTime
to a SQL TIMEorg.hibernate.type.OffsetDateTimeType
- Maps ajava.time.OffsetDateTime
to a SQL TIMESTAMPorg.hibernate.type.OffsetTimeType
- Maps ajava.time.OffsetTime
to a SQL TIMEorg.hibernate.type.ZonedDateTimeType
- Maps ajava.time.ZonedDateTime
to a SQL TIMESTAMPAs this relies on Java 8 and Hibernate still maintains compatibility back to Java 6, a new module
hibernate-java8
was added to isolate the Java 8 compatibility to just these classes. We will fold the classes from this module into hibernate-core once we baseline one Java 8.Original request
It would be cool to be able to persist the date time types newly introduced in Java 8 in a reasonable way. Currently the values are persisted as blobs effectively.
There are already a user type implementations for the backport project of JSR-310 but they unfortunately don't work with the types from the
java.time
package. The support has also been requested in the user forums.