標籤:
產生:
當使用hibernate查詢一個對象的時候,如果Session關閉,再調用該對象關聯的集合或者對象的時候,會產生懶載入異常!
解決方案:
方案一:
在Session關閉之前,查詢對象關聯的集合或者對象,所有在業務層的方法上添加:
public ElecUser findUserByLogonName(String name) {
String condition = " and o.logonName = ?";
Object [] params = {name};
List<ElecUser> list = elecUserDao.findCollectionByConditionNoPage(condition, params, null);
//資料庫表中存在該使用者,返回ElecUser對象
ElecUser elecUser = null;
if(list!=null && list.size()>0){
elecUser = list.get(0);
}
/***
* 解決懶載入異常
除了OID之外的其他屬性
*/
elecUser.getElecRoles().size();
return elecUser;
}
方案二:在Service層的方法中(Session關閉之前),初始化對象關聯的集合或者對象
public ElecUser findUserByLogonName(String name) {
String condition = " and o.logonName = ?";
Object [] params = {name};
List<ElecUser> list = elecUserDao.findCollectionByConditionNoPage(condition, params, null);
//資料庫表中存在該使用者,返回ElecUser對象
ElecUser elecUser = null;
if(list!=null && list.size()>0){
elecUser = list.get(0);
}
/***
* 解決懶載入異常
*/
Hibernate.initialize(elecUser.getElecRoles());
return elecUser;
}
方案三:在ElecUser.hbm.xml中,添加lazy=”false”,查詢使用者的同時,立即檢索查詢使用者關聯的角色集合:
<set name="elecRoles" table="elec_user_role" inverse="true" lazy="false">
<key>
<column name="userID"></column>
</key>
<many-to-many class="cn.itcast.elec.domain.ElecRole" column="roleID"/>
</set>
表示查詢使用者的時候,立即檢索使用者所關聯的角色
建議項目開發中不要在.hbm.xml中添加過多的lazy=false,這樣如果表關聯比較多,不需要查詢的對象也被載入了,效能會出現問題。
方案四:使用spring提供的過濾器OpenSessionInViewFilter,在web容器中添加該過濾器
在web.xml中添加:
要求:該過濾器一定要放置到strtus2的過濾器的前面,先執行該過濾器。
<!-- 添加spring提供的過濾器,解決hibernate的懶載入問題 -->
<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>*.do</url-pattern>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>
<!-- 配置struts2的過濾器,這是struts2啟動並執行核心 -->
<filter>
<filter-name>struts2</filter-name>
<filter-class>
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>*.do</url-pattern>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>
表示:OpenSessionInViewFilter過濾器實現的原理:
1:事務提交:spring提供的聲明式事務控制,仍然在業務層的方法進行處理,方法執行完畢後,事務會自動認可,如果出現異常,事務就會復原。但是它延遲了Session關閉的時間。
2:Session關閉:Session在頁面上進行關閉,此時當頁面上的資料載入完成之後,再關閉Session。
問題:如果你開發的系統對頁面資料載入比較大的時候,不適合使用
OpenSessionInViewFilter,這樣Session不能及時關閉,另一個Session就無法訪問,串連不夠使用,就會產生“假死”現象。
hibernate的懶載入問題