Cause and solution of “org.hibernate.LazyInitializationException: could not initialize proxy – no Session” error

In Hibernate, a common error faced by lots of developer is “org.hibernate.LazyInitializationException: could not initialize proxy – no Session“. In lots of forum the answer is no answer and most of forum have answer but there is no explanation for the beginners.

First, Lets reproduce this error in Hibernate.

Assume that Hibernate configuration (hibernate.cfg.xml) and  mapping file is already written.

Consider below snap of code and assume that function is written in class “DBManager”.

 public List<ChatMessage> getMessages() {
            List<ChatMessage> MessageList = new ArrayList<ChatMessage>();
            Configuration cf = new Configuration().configure();
            SessionFactory factory = cf.buildSessionFactory();
            Session session = null;
            try {
                  session = factory.openSession();
                  String SQL_QUERY = "from ChatMessage c";
                  Query query = session.createQuery(SQL_QUERY);
                  Iterator<ChatMessage> it = query.iterate();
                  while (it.hasNext()) {
                        ChatMessage c = it.next();
                        MessageList.add(c);
                         //If below line is commented then code throws an error
                        //System.out.println("In Manager - Msg - "+c.getMessage());
                  }

            } catch (Exception e) {
                  e.printStackTrace();
            } finally {
                  session.close();
            }

            return MessageList;
      }

In above code, i am trying to fetch the collection of class “ChatMessage”. In while loop, simply i am adding the object in ArrayList and at the end i am returning the List. Check that i have commented the SOP statement at the end of while loop.

Lets consider that other class is invoking this code. Code snap of other class is:

List<ChatMessage> msgList = dbManager.getMessages();
                  System.out.println(" Size : "+msgList.size());
                  for(ChatMessage chatMsg : msgList)
                  {
                        out.println(olMsg+"<span style='background:#"+colorCode+"'>"+chatMsg.getUserName()+"</span>"+chatMsg.getMessage()+"<br/><br/>");
                  }

Whenever this code executes, it will throw an error inside for loop at “chatMsg.getUserName()” because the lazy loading is true by default and as error also describes this. The best solution is to make “lazyLoad=false” in configuration file. The code will then run perfect, but why this error did come?

This error means that you’re trying to access a lazily-loaded property or collection, but the hibernate session is closed or not available . Lazy loading in Hibernate means that the object will not be populated (via a database query) until the property/collection is accessed in code. Hibernate accomplishes this by creating a dynamic proxy object that will hit the database only when you first use the object. In order for this to work, your object must be attached to an open Hibernate session throughout it’s lifecycle.

When we uncomment the SOP statement, program runs successfully, because it hits the object and therefore it initializes itself through hibernate session.

Posted

in

by

Tags:


Related Posts

Comments

10 responses to “Cause and solution of “org.hibernate.LazyInitializationException: could not initialize proxy – no Session” error”

  1. Jeeba Avatar

    Well the solutions works, but it has a problem, when you use a LAZy=”FALSE” then everytime you call that DAO, its going to fetch all the data requested, including data from other tables, the real solution is something called Open Session in View, that unfortunately i dont quite comprehend, but its basically have the session variable for all the time we want

    1. Jitendra Zaa Avatar

      Hi Jeeba,
      Thanks for good comment.
      You are right. soon i am going to publish that solution.

      1. Frank Avatar
        Frank

        soon you say? when is soon: this year, this century, ’til the end of the world?

        1. Jitendra Zaa Avatar

          Hey Frank,
          Thanks for your interest in article and its other solution. As per Jeeba comment, we have to keep our session open until we need that object. That is the only solution and this can be done by passing the Session object to the function where it creates the list and don’t close the session. If you want then i can write one more article however it is very easy to accomplish this.

          You can refer this URL also:
          http://docs.jboss.org/hibernate/core/3.3/reference/en/html/performance.html#performance-fetching-lazy

          Thanks,
          Jitendra Zaa

  2. Jitendra Zaa Avatar

    One more example to help to understand:

    s = sessions.openSession();
    Transaction tx = s.beginTransaction();

    User u = (User) s.createQuery("from User u where u.name=:userName")
    .setString("userName", userName).uniqueResult();
    Map permissions = u.getPermissions();

    tx.commit();
    s.close();

    Integer accessLevel = (Integer) permissions.get("accounts"); // Error!

  3. Arun Avatar
    Arun

    My mob no: +917204651195

  4. asdad Avatar
    asdad

    asdsad

  5. vsr Avatar
    vsr

    nice explanation

  6. Prakash Hingu Avatar
    Prakash Hingu

    cascaded is all and lazy load data also use @Transacational but it gives me “org.hibernate.LazyInitializationException”

Leave a Reply to ArunCancel reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Discover more from Jitendra Zaa

Subscribe now to keep reading and get access to the full archive.

Continue Reading