Unable to evaluate the expression method threw ‘org.hibernate.lazyinitializationexception’ exception.

The error “unable to evaluate the expression method threw ‘org.hibernate.lazyinitializationexception’ exception” occurs when a lazily loaded object is accessed after the Hibernate session has been closed or detached. In Hibernate, lazy loading is a feature that delays the loading of associated objects until they are explicitly requested.

Let’s consider an example to understand this error. Suppose we have two entities – Order and Customer. There is a one-to-one relationship between them, where an Order has a foreign key reference to a Customer. By default, Hibernate lazily loads the associated Customer object when it is accessed from an Order.


@Entity
public class Order {
    // Other fields and annotations

    @OneToOne(fetch = FetchType.LAZY)
    private Customer customer;

    // Getters and setters
}

@Entity
public class Customer {
    // Other fields and annotations

    // Getters and setters
}
    

When we load an Order using Hibernate, the associated Customer object won’t be loaded immediately. It is only loaded when we access the customer field. However, there are cases when we may try to access the customer field after closing the Hibernate session. This will result in the “org.hibernate.lazyinitializationexception” exception.


// Open a Hibernate session
Session session = sessionFactory.openSession();

// Retrieve the Order object
Order order = session.get(Order.class, orderId);

// Close the Hibernate session
session.close();

// Accessing the lazily loaded customer field will throw an exception
Customer customer = order.getCustomer(); // Throws a LazyInitializationException
    

To avoid this exception, we need to ensure that the Hibernate session is still active when accessing lazily loaded fields. One way to achieve this is by using the Open Session In View (OSIV) pattern. This pattern keeps the Hibernate session open until the view rendering is complete, allowing lazy loading to work properly. It is typically implemented using a filter or interceptor in a web application.

Another approach is to use the EAGER fetching strategy instead of the default LAZY strategy. In this case, the associated object is loaded immediately along with the main object. However, be cautious when using EAGER loading as it may result in loading unnecessary data and impact performance.


@Entity
public class Order {
    // Other fields and annotations

    @OneToOne(fetch = FetchType.EAGER)
    private Customer customer;

    // Getters and setters
}
    

Read more

Leave a comment