Umesh Awasthi
Umesh Awasthi

Reputation: 23587

Hibernate Lazy initialization problem

while learning a bit about hibernate i came across famous lazy initialization exception under below mentioned case

i have a class A which has reference to another class B and using hibernate i was trying to load class A using its id and than after closing the session i was trying to print some properties of class B thinking that hibernate might have initialized the object but all it did was a proxy object, here is the code snap

Session session=HibernateUtil.getSessionFactory().openSession();
        Transaction tx = session.getTransaction();
        try {
            tx.begin();
            a=(A)session.load(A.class, "40288184318d9a3c01318d9a3eea0001");
            tx.commit();

        } catch (Exception e) {
            log.error("Unable to complete the transcation"
                    + "Transcation will be roll backed", e);
            e.printStackTrace();
            tx.rollback();

        } finally {
            log.info("Closing the session");
            if (session != null && session.isOpen() == true){
                session.close();
            }
        }
        System.out.println(a.getUuid());
        System.out.println(a.getB().getShortDescription());
        System.out.println(a.getB().getLongDescription());
        System.out.println(a.getB().getName());

this code was giving me org.hibernate.LazyInitializationException: could not initialize proxy - no Session since i know it has given me only proxy for B and when i tried to get properties of B hibernate throws exception

i did a small change in my code and it worked well here is the changed version

    Session session=HibernateUtil.getSessionFactory().openSession();
    Transaction tx = session.getTransaction();
    try {
        tx.begin();
        a=(A)session.load(A.class, "40288184318d9a3c01318d9a3eea0001");
        tx.commit();

    } catch (Exception e) {
        e.printStackTrace();
        tx.rollback();

    } finally {
        //log.info("Closing the session");
        if (session != null && session.isOpen() == true){
            b=des.getB();
            session.close();
        }
    }
    a.setB(b);
    System.out.println(a.getUuid());
    System.out.println(a.getB().getShortDescription());
    System.out.println(a.getB().getLongDescription());
    System.out.println(a.getB().getName());
}

though it is working but i am not sure if this is correct approach or not, please suggest

Upvotes: 0

Views: 2978

Answers (1)

hvgotcodes
hvgotcodes

Reputation: 120188

Definitely NOT the right approach.

Understand what you want: you want to load A, and then get all Bs associated with A. Understand what you did: you loaded A, then set B to 'b', which might or might not have changed the value of B.

You have a number of options to do it correctly.

1) Use an open session in view filter in your app. Some people consider it an anti-pattern, but a lot of developers do it, and I personally think its ok.

2) Create a custom query which gets you everything you need in one go. You can write some hql that will get all Bs associated to an A when you fetch an A.

3) Call a.getB() while the session is active, and hibernate will fetch it for you.

4) Make the association not lazy, but I would not do that as it will be slow. If you always want Bs when you get A, then you can do it, but only in that case.

Upvotes: 3

Related Questions