BackendBench
Coffee

Home โ€บ Java exceptions โ€บ LazyInitializationException

Unchecked exception ยท org.hibernate

LazyInitializationException: causes and fixes

A lazily loaded association or collection was accessed after the Hibernate session had closed.

What it looks like

org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.acme.Order.items, could not initialize proxy - no Session

Extends HibernateException in org.hibernate.

What it means

Associations such as @OneToMany are loaded lazily by default: Hibernate puts a proxy in the field and runs the query the first time you touch it. That only works while the session (the persistence context) is open. Once the transaction ends, and the entity is detached, touching the proxy fails with this exception. It typically appears in the controller or in JSON serialisation, after the service method returned.

Common causes

How to fix it

  1. Fetch what you need inside the transaction: a JOIN FETCH query, an @EntityGraph, or Hibernate.initialize.
  2. Map entities to DTOs inside the service and return the DTO.
  3. Avoid switching associations to EAGER globally: it causes N+1 queries and large joins.
  4. Keep spring.jpa.open-in-view=false and fix the access pattern, so database work stays in the service layer.

Broken and fixed

fails
@Transactional
public Order get(Long id) { return repo.findById(id).orElseThrow(); }
// controller: order.getItems() -> no Session
works
@Query("select o from Order o join fetch o.items where o.id = :id")
Optional<Order> findWithItems(@Param("id") Long id);

๐Ÿ”Ž Unravel the failing code ๐Ÿ”Ž Unravel the fix

In Spring and enterprise code

Spring Boot enables open-in-view by default, which hides this error by keeping the session open during the web request but holds a database connection for the whole request. Many teams turn it off.

Debug it faster

Paste the whole stack trace into the stack trace beautifier to hide framework frames, jump to the root cause and find the first line of your own code. It runs in your browser, so the trace never leaves your machine.

Frequently asked questions

Is LazyInitializationException a checked or unchecked exception?

LazyInitializationException is an unchecked exception (it extends HibernateException, which is a RuntimeException), so you are not forced to catch it. Prevent it with validation, or handle it where the input enters the system.

Which package is LazyInitializationException in?

It lives in org.hibernate, so the import is import org.hibernate.LazyInitializationException;.

What is the first thing to check when I see LazyInitializationException?

Read the message and the first stack trace line in your own code. The usual causes are: Returning an entity from a transactional service and accessing a lazy collection in the controller or in Jackson; and Spring Boot's open-in-view being disabled (or never relevant for async or batch code).

Related exceptions

More tools you might need