The org.hibernate.LazyInitializationException: could not initialize proxy error is a common issue that can occur when working with the Hibernate ORM (Object-Relational Mapping) framework in a Spring Boot application. This error occurs when Hibernate is unable to initialize a proxy object, which is an object that is used to lazily load data from the database.

When a proxy object is created, it does not contain any data and is only used to load the data when it is accessed. This is known as lazy loading. However, if the data is not loaded before the session is closed, the proxy object will not be able to load the data and will throw the org.hibernate.LazyInitializationException: could not initialize proxy error.

There are a few common causes of this error:

  1. The session is closed before the proxy object is accessed: This can happen if the session is closed before the proxy object is accessed, for example, by closing the entity manager or the transaction too early. To fix this issue, make sure the session is open when the proxy object is accessed.

  2. The proxy object is accessed outside of a transaction: Hibernate requires a transaction to be active when initializing a proxy object. If the proxy object is accessed outside of a transaction, the org.hibernate.LazyInitializationException: could not initialize proxy error will be thrown.

  3. The fetch mode is set to lazy: By default, Hibernate uses lazy loading for all associations. If you want to load the associated data immediately, you can set the fetch mode to “eager”.

  4. The EntityGraph is not correctly configured: When using an EntityGraph, it is important to configure it correctly. If the EntityGraph is not correctly configured, the org.hibernate.LazyInitializationException: could not initialize proxy error will be thrown.

The fix

To fix the org.hibernate.LazyInitializationException: could not initialize proxy error, you need to make sure that the session is open when the proxy object is accessed, the proxy object is accessed within a transaction, the fetch mode is set to eager, and the EntityGraph is correctly configured. Additionally, you can use the OpenSessionInView pattern which keeps the session open throughout the entire request-response cycle, allowing the proxy objects to be initialized properly.

With a simple configuration change

Configure Hibernate with

<property name="hibernate.enable_lazy_load_no_trans" value="true"/>

or when using Spring, add the following property to your application.properties file:

spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true

There is a price to pay, as it will cause a performance hit. Hibernate will now initialize all lazy loaded objects, even if they are not accessed.

With a FetchType.EAGER

Instead of doing

@NotNull
@ManyToOne
@JoinColumn(name="video_id")
private VideoEntity video;

do

@NotNull
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name="video_id")
private VideoEntity video;

With a EAGER fetching when using Criteria

Just set Criteria fetch mode to FetchMode.EAGER

Criteria criteria = session.createCriteria(VideoScoreEntity.class);
criteria.setFetchMode("video", FetchMode.EAGER);