• Skip to primary navigation
  • Skip to content
  • Skip to primary sidebar

Thoughts on Java

  • Tutorials ▼
    • Hibernate & JPA Tutorials
    • Hibernate Tips
    • Tutorials on YouTube
  • Books & Training ▼
    • Hibernate Tips Book
    • Online Training
    • On-Site Training
  • Consulting ▼
    • Consulting Call
    • Project Coaching
  • About ▼
    • About Thoughts on Java
    • Support Thoughts on Java
    • Resources
  • Member Library
You are here: Home / Hibernate 5 / 5 new features in Hibernate 5 every developer should know
Special thanks to all Thoughts on Java Supporters for supporting this article!

5 new features in Hibernate 5 every developer should know

By Thorben Janssen 2 Comments

  • tweet 
  • share 
  • share 
  • share 
  • share 
  • share 
  • e-mail 

5 new features in Hibernate 5 every developer should know
 
The Hibernate team published the first Hibernate 5 release quite a while ago, and since then they introduced a bunch of new features. I explained several of them here on the blog, and it’s about time to have a look at the most popular ones. Based on the search traffic I get from google and my personal experience, the Java 8 support is the most popular change. But there are also some other features which might seem small but make common development tasks a bit easier.
 

Don’t want to read? You can watch it here!

Follow me on YouTube to not miss any new videos.

 

Support classes of the Date and Time API as BasicTypes

The new Date and Time API was one of the most anticipated changes in Java 8. The old java.util.Date has a lot of issues which got finally fixed.

Unfortunately, JPA 2.1 and Hibernate 4 don’t provide direct support for it. But that’s not a huge issue. It just takes a few lines of code to implement an AttributeConverter that maps a LocalDate.

But obviously, the explicit support as a BasicType is still a lot better. Hibernate implemented that in version 5.0. Since then you don’t need any additional annotations or converter to persist the classes of the Date and Time API. You can use them in the same way as any other supported attribute types.

When you persist this Book entity, Hibernate automatically maps the LocalDate to a JDBC DATE and persists it in the database. I get into more details about the mapping of the different Date and Time API classes in: How to persist LocalDateTime & Co with Hibernate 5

 

Get query results as a Stream

Introducing a new method to give you your query result as a Stream doesn’t sound like a big thing. But the stream method of Hibernate’s Query interface provides an additional benefit that makes it especially interesting for huge result sets. It fetches the result set in multiple batches and uses Hibernate’s ScrollableResults implementation to scroll through it. This approach is a great fit if you use a Stream to process the result set records one by one and helps you to implement your use case efficiently.

You can use the new method since Hibernate 5.2 to get your query results. The following code snippet shows a simple example that selects all Book entities from the database and processes them as a Stream.

You can read more about Hibernate’s stream method in How to get query results as a Stream with Hibernate 5.2.

 

Fetch multiple entities by their primary key

Fetching multiple entities by their ID is a very common use case. Most developers either implement it with a loop that calls the find method of the EntityManager for each primary key or with a JPQL query that checks all primary key values in an IN clause. The first option requires Hibernate to perform a database query for each primary key. That can create huge performance issues. The second one allows you to fetch all entities with one query and is obviously the better option.

Hibernate 5.1 introduced a third option that avoids the issues of the first and is easier to use than the second one. The new MultiIdentifierLoadAccess interface provides a comfortable option to load multiple entities with one query. You just need to call the byMultipleIds method on the Hibernate Session to get a MultiIdentifierLoadAccess interface and provide a list of primary key values to the multiLoad method.

As you can see in the log output, Hibernate creates only 1 query to select the 3 records from the database. That’s the same query as you would implement yourself but the API is a lot easier to use.

Hibernate’s implementation also provides an additional advantage: It splits huge lists of primary key values into multiple batches. This is sometimes required because some databases limit the number of elements in an IN clause.

I explained the new MultiIdentifierLoadAccess interface in more details in How to fetch multiple entities by id with Hibernate 5.

 

Join unassociated entities in a query

You can easily join mapped associations between entities in JPQL queries. The mapping already provides the required join conditions, and you don’t need to provide them in your query.

But what about entities that map associated database tables but have no mapped association?

And that’s not a rhetorical question.

Most entity models don’t map all the possible associations. They only map the ones that seem to provide value in the domain model and not the ones where 2 database tables (seemingly by accident) store the same foreign key. It also happens quite often that a to-many association with lots of records on the many side doesn’t get mapped with Hibernate. The risk that someone calls the getter of the association and fetches several hundred or thousand entities is just too high.

That’s totally fine as long as you just look at the domain model. You probably don’t need these associations in the model. But that doesn’t mean that you don’t need them in one of your JPQL queries.

If that’s the case, you have 3 options:

  1. Model the association between the entities or
  2. Use a cross join in your JPQL query which might create performance issues or
  3. Use Hibernate’s proprietary JOIN clause.

I prefer option 3. It’s the easiest and most natural one.

Since Hibernate 5.1, you can use an SQL-like syntax to join entities without a modeled association.

 

@Repeatable annotations

Repeatable annotations are one of the smaller changes in Java 8. It allows you to annotate a class, attribute or interface with the same annotation multiple times. A typical JPA example in which you want to do that is defining multiple named queries for an entity.

So far, you had to annotate your entity with a @NamedQueries annotation which contained an array of @NamedQuery annotations. The annoying thing about that is that the @NamedQueries annotation is just a container. It doesn’t provide any value on its own.

Since Hibernate 5.2, you don’t have to do that anymore. At least not as long as you use Hibernate’s version of the org.hibernate.annotations.NamedQuery annotation. @NamedQuery and a lot of other Hibernate annotations are now repeatable and can be assigned multiple times. As you can see in the following code snippet, that makes the code easier to read and is much more comfortable to use.

 

Summary

Hibernate 5 brought a lot of changes, but these 5 were the ones which I like the best and which I actively used the most, so far. Especially the support for the Date and Time API and the new MultiIdentifierLoadAccess interface have been helpful.

Hibernate obviously introduced more than just these 5 changes. There is a new bootstrapping API, for example, and the Session interface now extends JPA’s EntityManager. These changes are all nice and interesting, but they didn’t have an impact on my projects because I’m working in a Java EE environment.

That might be completely different for you. So, which are your favorite changes in Hibernate 5? Are there any features which you don’t want to miss in your daily work? Please tell me about them in the comments.

  • tweet 
  • share 
  • share 
  • share 
  • share 
  • share 
  • e-mail 

Related posts:

  1. Mapping Definitions in JPA and Hibernate – Annotations, XML or both?
  2. Hibernate Tips: How to exclude unchanged columns from generated update statements
  3. Best Practices for Many-To-One and One-To-Many Association Mappings
  4. 10 Common Hibernate Mistakes That Cripple Your Performance
Become a Thoughts on Java Supporter to claim your member perks and to help me write more articles like this.

Filed Under: Hibernate 5, Hibernate Advanced Tagged With: Mapping, Query

Implement Your Persistence Layer with Ease

Learn More About Hibernate

Need Some Help with Your Project?

Reader Interactions

Comments

  1. Bernd Kursawe says

    March 15, 2017 at 10:45 am

    In the section “Get query results as a Stream” your example code contains:

    List books = session.createQuery(“SELECT b FROM Book b”, Book.class).getResultList();
    books.stream()…

    But this is not the way of using the new Hiberante functionality you’ve described. It should be:

    Stream books = session.createQuery(“SELECT b FROM Book b”, Book.class).stream();
    books.map(b -> b.getTitle() + ” was published on ” + b.getPublishingDate())
    .forEach(m -> log.info(m));

    (from you website //thoughts-on-java.org/get-query-results-stream-hibernate-5/)

    Reply
    • Thorben Janssen says

      March 15, 2017 at 10:47 am

      Oh, …
      I referenced the wrong code snippet.

      Thanks Bernd!

      Reply

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Primary Sidebar

Join over 10.000 developers
in the
Thoughts on Java Library

Ebooks Sidebar Get free access to ebooks, cheat sheets and training videos.
Join Now!
Don't like ads?
Become a Thoughts on Java Supporter.
Special Launch Price

Let’s Connect


Thorben Janssen
Independent consultant, trainer and author
  • Facebook
  • GitHub
  • Google+
  • LinkedIn
  • Twitter
  • xing
  • YouTube

Speaking at

7th February 2019
JUG Ostfalen (Germany):
Hibernate Tips 'n' Tricks: Typische Probleme schnell gelöst (Talk - German)

19th March 2019
JavaLand 2019 (Germany):
Hibernate Tips 'n' Tricks: Typische Probleme schnell gelöst (Talk - German)

21st March 2019
JavaLand 2019 (Germany):
Hibernate + jOOQ + Flyway = Die besten Frameworks in einem Stack (1-day Workshop - German)

6th-10th May 2019
JAX 2019 (Germany):
Hibernate Workshop: Komplexe Lösungen jenseits von CRUD (2-day Workshop - German)

6th-10th May 2019
JAX 2019 (Germany):
Spring Data JDBC vs. Spring Data JPA – Wer macht das Rennen? (Talk - German)

6th-10th May 2019
JAX 2019 (Germany):
Microservices mit Hibernate – typische Probleme und Lösungen (Talk - German)

Looking for an on-site training?

Featured Post

14 YouTube Channels You Should Follow in 2019

Getting Started With Hibernate

Entities or DTOs – When should you use which projection?

Ultimate Guide – Association Mappings with JPA and Hibernate

Ultimate Guide to JPQL Queries with JPA and Hibernate

Recent Posts

  • Hibernate Tips: How to Customize a Constructor Expression for Different Subclasses
  • Hibernate Tips: How to Map java.time.Year with JPA and Hibernate
  • Why, When and How to Use DTO Projections with JPA and Hibernate
  • Hibernate Tip: Map a bidirectional one-to-one association with shared composite primary key
  • Implementing the Repository pattern with JPA and Hibernate
  • Hibernate Tips: How to Handle NULL Values while Ordering Query Results in a CriteriaQuery
  • 6 Hibernate Best Practices for Readable and Maintainable Code
  • Can you use Hibernate/EclipseLink/JPA for your microservice?
  • 14 YouTube Channels You Should Follow in 2019
  • Hibernate Tips: How To Map an Entity to a Query
Don't like ads?
Become a Thoughts on Java Supporter.

Copyright © 2019 Thoughts on Java

  • Impressum
  • Disclaimer
  • Privacy Policy