2009-07-01 58 views
7

考慮這樣的場景:如何在會話關閉後使用hibernate訪問延遲加載的字段?

  • 我已加載父實體通過Hibernate
  • 家長包含的子集是大懶加載
  • Hibernate的Session是在用戶這一初始加載後關閉查看父數據
  • 用戶可以選擇要查看的懶孩子收集
  • 的內容我現在要載入該集合

加載此集合的方式/最佳方式是什麼?

  • 假設會話中的視圖不是一個選項,因爲只有在用戶查看父節點並決定查看子節點後纔會獲取Children集合。
  • 這是一項服務,將通過基於Web和桌面的客戶端遠程訪問。

感謝。

回答

3

我正在做什麼用戶正在尋找一些假設,但好像你只是想找回孩子,如果用戶已經觀看的家長和真正想看到孩子們。

爲什麼不嘗試打開一個新的會話,並通過他們的父母取的孩子嗎?沿着線的東西...

criteria = session.createCriteria(Child.class); 
criteria.add(Restrictions.eq("parent", parent)); 
List<Child> children = criteria.list(); 
+0

不錯的一個。我錯過了你可以在限制中指定對象。 – 2009-07-02 10:46:42

+1

如果「父」字段是集合,該怎麼辦? – Damian 2011-10-29 00:00:22

7

的延遲的集合可以通過使用被加載狀態,Hibernate.initialize(parent.getCollection()),除了需要被附接到活動會話的父對象。

該解決方案採用父實體和延遲加載字段的名稱和滿載的集合返回的實體。

不幸的是,家長需要被重新連接到新開的會議,我不能用一個參考延遲的集合,因爲這將參考實體的分離版本;因此fieldName和反射。出於同樣的原因,這必須返回附加的父實體。

Parent parentWithChildren = dao.initialize(parent,"lazyCollectionName"); 

的方法:

所以在OP的情況下,這種調用可以當用戶選擇查看懶惰集合所做

public Entity initialize(Entity detachedParent,String fieldName) { 
    // ...open a hibernate session... 
    // reattaches parent to session 
    Entity reattachedParent = (Entity) session.merge(detachedParent); 

    // get the field from the entity and initialize it 
    Field fieldToInitialize = detachedParent.getClass().getDeclaredField(fieldName); 
    fieldToInitialize.setAccessible(true); 
    Object objectToInitialize = fieldToInitialize.get(reattachedParent); 

    Hibernate.initialize(objectToInitialize); 
    return reattachedParent; 
} 
0

休眠處理以不同的方式收集該正常的領域。

在我的工作中,我們通過剛剛在初始化,我們需要在個案基礎的情況下,初始加載領域解決此得到。例如,在由交易包圍的門面load方法,你可能有:

public Parent loadParentWithIntent1(Long parentId) 
{ 
    Parent parent = loadParentFromDAO(); 

    for (Child c : parent.getChildren()) 
    { 
    c.getField1(); 
    } 
} 

,我們有不同的門面呼籲每個意圖。這基本上實現了你所需要的,因爲當你需要它們時,你會加載這些特定的字段,這只是在加載時將它們放入會話中。