Hibernate懒惰初始化问题 [英] Hibernate Lazy initialization problem

查看:155
本文介绍了Hibernate懒惰初始化问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在学习一些关于hibernate的知识时,我遇到了下面提到的例子中的着名的懒惰初始化异常。我有一个类A,它引用了另一个类B并使用了hibernate我正在尝试使用它的id加载类A,并且在关闭会话后我试图打印一些B类属性,认为hibernate可能已经初始化了对象,但它所做的只是一个代理对象,下面是代码快照 p>

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

} catch(Exception e){
log.error(无法完成transcation
+Transcation将被回滚,e);
e.printStackTrace();
tx.rollback();

}最后{
log.info(关闭会议);
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());

这段代码给我 org.hibernate.LazyInitializationException:无法初始化代理 - 没有会话因为我知道它给了我只有代理B,当我试图获得B的属性Hibernate抛出异常



我做了在我的代码中的一个小改动,它在这里运行得很好,是改变后的版本。

  Session session = HibernateUtil.getSessionFactory()。openSession ); 
Transaction tx = session.getTransaction();
尝试{
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());
}

虽然它正在运作,但我不确定这是否正确方法,请提出建议

解决方案

绝对不是正确的做法。



了解你想要什么:你想加载A,然后获得与A相关的所有B.
了解你做了什么:你加载了A,然后将B设置为'b',这可能会或可能没有改变B。

您有许多选项可以正确执行此操作。

1)在您的应用中使用视图过滤器中的打开会话。有些人认为这是一种反模式,但很多开发人员都这样做,我个人认为它是可以的。

2)创建一个自定义查询,让您获得所有的东西需要一气呵成。 3)调用 a.getB() / code>,而会话处于活动状态,并且hibernate会为你取回它。



4)使关联不是懒惰的,但我不会那么做它会很慢。如果你总是想要B时,你可以做到,但只有在这种情况下。


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

解决方案

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.

这篇关于Hibernate懒惰初始化问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆