java-web hibernate中的懒加载问题
生活随笔
收集整理的這篇文章主要介紹了
java-web hibernate中的懒加载问题
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
java-web hibernate中的懶加載問題
懶加載異常
1.延遲加載機(jī)制 延遲加載機(jī)制是為了避免一些無謂的性能開銷而提出來的,所謂延遲加載就是當(dāng)在真正需要數(shù)據(jù)的時候,才真正執(zhí)行數(shù)據(jù)加載操作。在Hibernate中提供了對實(shí)體對象的延遲加載以及對集合的延遲加載,另外在Hibernate3中還提供了對屬性的延遲加載。實(shí)體對象的延遲加載:如果想對實(shí)體對象使用延遲加載,必須要在實(shí)體的映射配置文件中進(jìn)行相應(yīng)的配置, <hibernate-mapping><class?name=”com.enterise.domain.User”?table=”user”?lazy=”true”> 通過將class的lazy屬性設(shè)置為true(默認(rèn)情況下是true),來開啟實(shí)體的延遲加載特性。 User?user=(User)session.load(User.class,”1”); 當(dāng)運(yùn)行到這里的時候: Hibernate并沒有發(fā)起對數(shù)據(jù)的查詢,如果我們此時通過一些調(diào)試工具(比如JBuilder2005的Debug工具),觀察此時user對象的內(nèi)存快照,我們會驚奇的發(fā)現(xiàn),此時返回的可能是User$EnhancerByCGLIB$$bede8986類型的對象,而且其屬性為null,這是怎么回事?還記得前面我曾講過session.load()方法,會返回實(shí)體對象的代理類對象,這里所返回的對象類型就是User對象的代理類對象。在Hibernate中通過使用CGLIB,來實(shí)現(xiàn)動態(tài)構(gòu)造一個目標(biāo)對象的代理類對象,并且在代理類對象中包含目標(biāo)對象的所有屬性和方法,而且所有屬性均被賦值為null。通過調(diào)試器顯示的內(nèi)存快照,我們可以看出此時真正的User對象,是包含在代理對象的CGLIB$CALBACK_0.target屬性中 System.out.println(user.getName()); 當(dāng)運(yùn)行到處時,此時調(diào)用user.getName()方法,這時通過CGLIB賦予的回調(diào)機(jī)制,實(shí)際上調(diào)用CGLIB$CALBACK_0.getName()方法,當(dāng)調(diào)用該方法時,Hibernate會首先檢查CGLIB$CALBACK_0.target屬性是否為null,如果不為空,則調(diào)用目標(biāo)對象的getName方法,如果為空,則會發(fā)起數(shù)據(jù)庫查詢,生成類似這樣的SQL語句:select?*?from?user?where?id=’1’;來查詢數(shù)據(jù),并構(gòu)造目標(biāo)對象,并且將它賦值到CGLIB$CALBACK_0.target屬性中。???這樣,通過一個中間代理對象,Hibernate實(shí)現(xiàn)了實(shí)體的延遲加載,只有當(dāng)用戶真正發(fā)起獲得實(shí)體對象屬性的動作時,才真正會發(fā)起數(shù)據(jù)庫查詢操作。所以實(shí)體的延遲加載是用通過中間代理類完成的,所以只有session.load()方法才會利用實(shí)體延遲加載,因?yàn)橹挥衧ession.load()方法才會返回實(shí)體類的代理類對象。
get()無懶加載特性,馬上執(zhí)行SQL查詢.?
load()有懶加載特性,會返加一個代理對象,所以永遠(yuǎn)不為null,先不執(zhí)行SQL,要取對象的值時才執(zhí)行SQL語句,前題session不能關(guān)閉,<class>標(biāo)簽上lazy不為false.?
問題:懶加載異常 org.apache.jasper.JasperException:?org.hibernate.LazyInitializationException:?failed?to?lazily?initialize?a?collection?of?role:?com.enterise.always.oa.bean.User.roles,?no?session?or?session?was?closed 出現(xiàn)問題的原因:在jsp使用getxxx();去獲取與這個對象相關(guān)連的對象的屬性的時候,就會出現(xiàn)初始化異常的信息,是由于對于相關(guān)聯(lián)的session已經(jīng)關(guān)閉。 解決機(jī)制: 1.在相關(guān)聯(lián)的屬性上設(shè)置:lazy?=?"false"; 2.使用過濾器(一定要配置在spring初始化容器下面): <filter>
? ? ? ? <filter-name>OpenSessionInViewFilter</filter-name>
? ? ? ? <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
? ?</filter>
? ?<filter-mapping>
? ? ? ? <filter-name>OpenSessionInViewFilter</filter-name>
? ? ? ? <url-pattern>*.action</url-pattern> ????<filter-mapping>
轉(zhuǎn)載于:https://my.oschina.net/liangzhenghui/blog/191283
總結(jié)
以上是生活随笔為你收集整理的java-web hibernate中的懒加载问题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2019传智python就业班视频_20
- 下一篇: easyUI tabs 显示与隐藏 ta