2011-03-17 33 views
3

錯誤爲failed to lazily initialize a collection, no session or session was closed延遲獲取會話錯誤

有很多人問幾乎相同的問題,但分辨率並不那麼直觀。而且,我覺得有必要發佈另一個問題來形容奇怪的錯誤信息:(我不打算在這裏粘貼的源代碼,因爲它太長)

DEBUG [main] (AbstractPlatformTransactionManager.java:365) - Creating new transaction with name [com.bee32.plover.orm.feaCat.FeaturePlayer.tcList]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; '' 
DEBUG [main] (HibernateTransactionManager.java:493) - Opened new Session [[email protected]] for Hibernate transaction 
DEBUG [main] (HibernateTransactionManager.java:523) - Not preparing JDBC Connection of Hibernate Session [[email protected]] 
DEBUG [main] (HibernateTemplate.java:397) - Found thread-bound Session for HibernateTemplate 
Hibernate: /* criteria query */ select 
    ... 

ERROR [main] (LazyInitializationException.java:42) - failed to lazily initialize a collection, no session or session was closed 
org.hibernate.LazyInitializationException: failed to lazily initialize a collection, no session or session was closed 
    at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:380) 
    ... 
    at java.util.HashSet.<init>(HashSet.java:116) 
    ... 
    at org.hibernate.loader.Loader.list(Loader.java:2124) 
    ... 
    at org.springframework.orm.hibernate3.HibernateTemplate$5.doInHibernate(HibernateTemplate.java:590) 
    ... 

DEBUG [main] (HibernateTemplate.java:422) - Not closing pre-bound Hibernate Session after HibernateTemplate 
DEBUG [main] (AbstractPlatformTransactionManager.java:843) - Initiating transaction rollback 
DEBUG [main] (HibernateTransactionManager.java:672) - Rolling back Hibernate transaction on Session [[email protected]] 
DEBUG [main] (HibernateTransactionManager.java:734) - Closing Hibernate Session [[email protected]] after transaction 

正如你所看到的,當lazy-fetch被觸發時,發生錯誤,已經有一個線程綁定的會話,並且在事務回滾之前它還沒有關閉。

那麼,它爲什麼報告有no session or session was closed

編輯 的相關來源:

@Transactional 
public void tcList() { 
    for (Cat cat : dao.list()) { 
     System.out.println("Saved cat: " + cat); 
    } 
} 
+0

你在JUnit測試用例中運行這個嗎? – 2011-03-17 19:30:17

回答

2

線程有一個會話綁定到它,但是是否由本會話管理的catList?該會話可能已通過hibernate模板在dao.list()內部關閉,該模板負責處理樣板代碼。

排除問題的一種方法是在返回列表之前調用dao.list()函數內的list.get(0).someGetter()。這將填充實際值的列表,不應該導致延遲初始化異常。如果Cat由延遲初始化的其他對象組成,則應該爲它們調用getter屬性,以防您想要使用這些屬性。

另外,嘗試刪除dao.list()方法上的任何Transactional註釋(如果有的話)。使用由調用函數創建的事務,而不是使用Propagation_Required屬性。如果你在dao.list()上使用了@Transactional,事務管理器可能會從這個函數返回時觸發一個transaction.commit()/ session.close(),所以catList變成一個分離的實體,所有的貓都是仍然代理。

0

實體可能會從會話和懶加載收集被分離只是一個代理?如果你想使用它,你需要將它合併到一個會話中?

+0

合併是一項代價高昂的操作 – BDR 2014-01-30 16:26:46

0

這意味着您正在嘗試加載/初始化會話中的集合。也許你必須保持會話活着,直到你完成你的操作.....意味着你必須使用一些膠水代碼來管理你的會話資源...... ppl會建議初始化實體的set方法中的懶惰集合。使用惰性取指就像沒有意義的一樣,直到操作可能是最好的方式。保持活動狀態。