hibernate Lazy Loading vs Eager Loading Scope


Example

For those who haven't played with these two designs, the scope of lazy and eager is within a specific Session of SessionFactory. Eager loads everything instantly, means there is no need to call anything for fetching it. But lazy fetch usually demands some action to retrieve mapped collection/object. This sometimes is problematic getting lazy fetch outside the session. For instance, you have a view which shows the detail of the some mapped POJO.

@Entity
public class User {
    private int userId;
    private String username;
    @OneToMany
    private Set<Page> likedPage;

    // getters and setters here
}

@Entity
public class Page{
    private int pageId;
    private String pageURL;

    // getters and setters here
}

public class LazzyTest{
    public static void main(String...s){
        SessionFactory sessionFactory = new SessionFactory();
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();
        
        User user = session.get(User.class, 1);
        transaction.commit();
        session.close();
        
        // here comes the lazy fetch issue
        user.getLikedPage();
    }
}

When you will try to get lazy fetched outside the session you will get the lazyinitializeException. This is because by default fetch strategy for all oneToMany or any other relation is lazy(call to DB on demand) and when you have closed the session, you have no power to communicate with database. so our code tries to fetch collection of likedPage and it throws exception because there is no associated session for rendering DB.

Solution for this is to use:

  1. Open Session in View - In which you keep the session open even on the rendered view.
  2. Hibernate.initialize(user.getLikedPage()) before closing session - This tells hibernate to initialize the collection elements