org.hibernate.LazyInitializationException: could not initialize proxy - no Sessi

異常:
org.hibernate.LazyInitializationException: could not initialize proxy - no Session
at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:57)
at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:111
)

原因:hibernate3 many-to-one的默認選項是 lazy = "proxy"
解決方法:<many-to-one>  & <set> 中設置 lazy="false"
 
HIBERNATE的持久化對象加載策略。 
延遲加載, 也就是用到的時候纔去加載.這樣可以提高一些性能. 
Hibernate
lazy loading 採用了一個HibernateSession來管理session,它的邏輯是每進行一次數據庫操作,就開新的session,操作完成後立即關閉該session。這樣做的好處是可以嚴格關閉session,避免菜鳥級的錯誤,但是hibernate.org並不推薦這麼做。因爲這不適合lazy loading
,也不適合跨方法的事務。

比如在我們的應用中,user->post形成一對多的映射,User中有一個包含postList

User中,有多個屬性:namepasswordphone等,還有一個List類型的posts。當我們對posts使用lazy laoding的時候,hibernate會在獲得User對象的時候,僅僅返回name,password,phone等基本屬性,當你訪問posts的時候,它纔會從數據庫中提取posts需要的數據,這就是所謂lazy laoding。但是在我們的系統中,session是被立即關閉的,也就是在讀取了name,password,phone等基本屬性後,session已經close了,再進行lazy loaiding
就會有異常。
解決辦法是在close session之前,調用Hibernate.initialize(user.getPosts()),告訴系統,user.getPosts()是需要lazy laoding的。但是這樣做會破壞HibernateSession
類的封裝.
後來採用所謂的OpenSessionInView模式,把session的週期交給servlet filter來管理,每當有request進來,就打開一個sessionresponse結束之後再關閉它,這樣可以讓session存在於整個請求週期中。


Hibernate中Lazy延遲加載 
Hibernate有關one-to-one和many-to-one在查詢中的父親端lazy問題 
Hibernate3在關聯上有lazy這個屬性,如果是Hibernate2,應該是設置outer-join="false",然後被關聯的對象,在class那個地方設置lazy="true".首先,對於many-to-one的問題,可以在父親端的class標籤中設置lazy來解決,這樣,在查詢兒子的時候,不會發送多餘的sql .
對於one-to-one,在hibernate2裏面,由於one-to-one裏面沒有lazy的選項,所以只能通過設置outer-join="false"來解決。而hibernate3已經加入了lazy,所以不會有這個問題。 
總體來說,如果你發現你查詢兒子的時候,有多餘的sql發送,那一定是你對hibernate的誤用..

在hibernate 的one-to-many,many-to-one,many-to-many中,爲了效率的提高,我們一般都採用lazy機制,但使用spring的getHibernateTemplate().save(Object)時,HibernateTemplate試圖每次在execute之前去獲得Session,執行完就力爭關閉Session 。也就是說Hibernate的Lazy初始化1:n關係時,你必須保證是在同一個Session內部使用這個關係集合,不然Hiernate將拋出Failed to lazily initialize a collection - no session or session was closed的例外。


Hibernate中的對象的關聯(association)的設置還是不夠靈活,實際應用中有的地方需要lazy load,有的地方又不需要,其實還有的地方就根本不需要使用association。而在Hibernate中,只能在影射文件中設置一種方式,像我們這樣的應用,我是不敢輕易使用open session in view的(慢點總比lock住要好),只能是要麼不設置association,要麼就是lazy=true的。以前的分類信息只用了一個many to one的關係,代價還可以忍受,但現在關係越來越複雜了,再多加幾個的話,所要付出的performance,帶寬等方面的代價恐怕就不能忽略了,即使使用cache提高一點performance,對帶寬的浪費也還是不可原諒的。

 

發佈了56 篇原創文章 · 獲贊 0 · 訪問量 1485
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章