2011-08-03 94 views
0

,同时学习一些关于休眠我碰到著名的延迟初始化例外情况如下所述情况Hibernate延迟初始化的问题

我有一个具有参照其他B类和使用Hibernate我尝试加载类A类A使用ID和比最后,我试图打印冬眠可能已经初始化的对象B类思维的一些性质的会议之后,但它所作的只是一个代理对象,这里是代码卡

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()); 

验证码给我org.hibernate.LazyInitializationException: could not initialize proxy - no Session,因为我知道它给了我只有代理B和当我试图让乙休眠的特性抛出异常

我做我的代码中的微小变化,它的工作好这里是更改后的版本

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()); 
} 

虽然它的工作,但如果这个我不知道是否正确的方法,请建议

回答

3

绝对不是正确的做法。

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

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

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

2)创建一个自定义查询,让您一次性获得所需的一切。你可以写一些hql,当你获取一个A时,所有的B都将与A相关联。

3)当会话处于活动状态时,拨打a.getB(),休眠会为你取回。

4)使协会不懒惰,但我不会那样做,因为它会很慢。如果当你得到A时你总是想要Bs,那么你可以做到,但只有在这种情况下。

+0

同意你的观点,我已经听说过这个,可以尝试一下,关于第二个我想避免定制HQL的时间。关于第三个我正在做的,我所做的所有可能是错误的是,保存在另一个对象的引用,以备将来使用,因为会话关闭不会让我得到参考 –

+0

只是一个补充我只有一个参考B在一个并且这不会是一个 –

+0

@umesh中的b的集合,加载后立即调用'a.getB()'将允许您在将来的任何时候调用'getB()';无需保存参考... – hvgotcodes