Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Hibernate Tips: How to Initialize Lazy Relationships Within a Query

DZone's Guide to

Hibernate Tips: How to Initialize Lazy Relationships Within a Query

Learn how you can initialize a lazy relationship within a query to avoid a LazyInitializationExceptions error being thrown.

· Database Zone ·
Free Resource

Discover Tarantool's unique features which include powerful stored procedures, SQL support, smart cache, and the speed of 1 million ACID transactions on a single CPU core!

Hibernate Tips is a series of posts in which I describe a quick and easy solution for common Hibernate questions. Some of the most popular tips are also available as a book.

If you have a question for a future Hibernate Tip post, please leave a comment below.

Get more videos from the Hibernate Tips playlist.

Question

How can I initialize a lazy relationship within a query to avoid LazyInitializationExceptions?

Solution

Hibernate throws a LazyInitializationExceptions if you try to use the attribute of a lazily fetched relationship outside of an active Hibernate Session.

EntityManager em = emf.createEntityManager();
em.getTransaction().begin();

Author a = em.createQuery("SELECT a FROM Author a WHERE id = 1", Author.class).getSingleResult();

em.getTransaction().commit();
em.close();

log.info(a.getFirstName() + " " + a.getLastName() + " wrote " + a.getBooks().size() + " books.");

You can avoid that by initializing the relationship before you close the session. Hibernate and JPA support different ways to do that. The easiest one is a JOIN FETCH statement within a query, like the one in the following code snippet.

EntityManager em = emf.createEntityManager();
em.getTransaction().begin();

Author a = em.createQuery("SELECT a FROM Author a JOIN FETCH a.books WHERE a.id = 1", Author.class).getSingleResult();

em.getTransaction().commit();
em.close();

log.info(a.getFirstName()+" "+a.getLastName()+" wrote "+a.getBooks().size()+" books.");

The additional FETCH keyword tells Hibernate to not only join the entity for the query but also to fetch it from the database to initialize the attribute. This prevents LazyInitializationExceptions if you access the relationship attribute outside of an active Hibernate Session.

If you liked this post, check out my book Hibernate Tips: More than 70 solutions to common Hibernate problems.

Discover Tarantool's unique features such as powerful stored procedures, SQL support, smart cache, and the speed of 1 million ACID transactions on a single CPU.

Topics:
hibernate ,jpa ,database ,tutorial ,querying ,lazy initialization

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}