2011-08-03 93 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