← Debugging Guides

阅读中文版本

Java — Hibernate LazyInitializationException outside a session

Fix LazyInitializationException by fetching the needed associations within the transaction or using DTOs.

intermediatedebuggingjavahibernate

Symptoms

  • org.hibernate.LazyInitializationException: could not initialize proxy - no Session
  • It works inside a service but fails during JSON serialization
  • Accessing a collection after the transaction ends throws
  • The exception appears in the controller or view layer

Possible causes

  • A lazy association is accessed after the session or transaction closed
  • The entity is returned outside the transactional boundary and serialized later
  • Open Session in View is disabled
  • The association was not fetched eagerly for this use case

Diagnosis steps

Locate where the association is accessed

grep -rn "getItems\|getOrders()\|@OneToMany\|@ManyToOne" src

Interpretation

Accessing the association outside the service transaction, such as in serialization, is the usual trigger.

Fetch within the transaction

join fetch / EntityGraph on the repository query

Interpretation

Fetching the association while the session is open loads it before the entity leaves the boundary.

Map to a DTO inside the transaction

orderMapper.toDto(order)

Interpretation

A DTO populated inside the transaction carries plain data that needs no session later.

Root cause

A lazily loaded association was accessed after its persistence context closed, so Hibernate had no session to run the loading query and raised LazyInitializationException.

Fix

Fetch the associations you need within the transaction using join fetch or an entity graph, or return DTOs built inside the transaction instead of detached entities.

Verify the fix

Exercise the same request and confirm the association loads without the exception, and confirm the returned data contains the expected related rows.

Symptom walkthrough

Accessing a mapped association after the transaction ends throws LazyInitializationException: could not initialize proxy - no Session. It typically appears in the controller, view or JSON serialization layer, while the same data loads fine inside the service method. The entity left the persistence context and its lazy associations can no longer be initialized on demand.

Fix in practice

Fetch the needed associations inside the transaction with a join fetch or an entity graph, or map entities to DTOs before the transaction closes. This keeps all required data loaded while a session is available. Enabling open-session-in-view hides the problem and can hold connections open longer, so prefer explicit fetching.

Verification

Repeat the request and confirm the association loads without the exception and that the response contains the expected related data. Loading correctly, not merely not throwing, confirms the fetch strategy is right.

Diagnostic commands

Check the behavior with commands like these:

grep -rn "getItems\|getOrders()\|@OneToMany\|@ManyToOne" src
join fetch / EntityGraph on the repository query
orderMapper.toDto(order)