你的位置:首页 > Java教程

[Java教程]hibernate的懒加载问题


产生原因:

当使用hibernate查询一个对象的时候,如果Session关闭,再调用该对象关联的集合或者对象的时候,会产生懒加载异常!

 

解决方案:

方案一:

在Session关闭之前,查询对象关联的集合或者对象,所有在业务层的方法上添加:

 1 public ElecUser findUserByLogonName(String name) { 2  3 String condition = " and o.logonName = ?"; 4  5 Object [] params = {name}; 6  7 List<ElecUser> list = elecUserDao.findCollectionByConditionNoPage(condition, params, null); 8  9 //数据库表中存在该用户,返回ElecUser对象10 11 ElecUser elecUser = null;12 13 if(list!=null && list.size()>0){14 15 elecUser = list.get(0);16 17 }18 19 /***20 21 * 解决懒加载异常22 23 除了OID之外的其他属性24 25 */26 27 elecUser.getElecRoles().size();28 29 return elecUser;30 31 }

View Code

 

方案二:在Service层的方法中(Session关闭之前),初始化对象关联的集合或者对象

 1 public ElecUser findUserByLogonName(String name) { 2  3 String condition = " and o.logonName = ?"; 4  5 Object [] params = {name}; 6  7 List<ElecUser> list = elecUserDao.findCollectionByConditionNoPage(condition, params, null); 8  9 //数据库表中存在该用户,返回ElecUser对象10 11 ElecUser elecUser = null;12 13 if(list!=null && list.size()>0){14 15 elecUser = list.get(0);16 17 }18 19 /***20 21 * 解决懒加载异常22 23 */24 25 Hibernate.initialize(elecUser.getElecRoles());26 27 return elecUser;28 29 }

View Code

 

 

方案三:在ElecUser.hbm.

 1 <set name="elecRoles" table="elec_user_role" inverse="true" lazy="false"> 2  3 <key> 4  5 <column name="userID"></column> 6  7 </key> 8  9 <many-to-many class="cn.itcast.elec.domain.ElecRole" column="roleID"/>10 11 </set>

View Code

表示查询用户的时候,立即检索用户所关联的角色

建议项目开发中不要在.hbm.

 

方案四:使用spring提供的过滤器OpenSessionInViewFilter,在web容器中添加该过滤器

在web.

要求:该过滤器一定要放置到strtus2的过滤器的前面,先执行该过滤器。

 1 <!-- 添加spring提供的过滤器,解决hibernate的懒加载问题 --> 2  3 <filter> 4  5 <filter-name>OpenSessionInViewFilter</filter-name> 6  7 <filter-class> 8  9 org.springframework.orm.hibernate3.support.OpenSessionInViewFilter10 11 </filter-class>12 13 </filter>14 15 <filter-mapping>16 17 <filter-name>OpenSessionInViewFilter</filter-name>18 19 <url-pattern>*.do</url-pattern>20 21 <url-pattern>*.jsp</url-pattern>22 23 </filter-mapping>24 25 <!-- 配置struts2的过滤器,这是struts2运行的核心 -->26 27 <filter>28 29 <filter-name>struts2</filter-name>30 31   <filter-class>32 33 org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter34 35 </filter-class>36 37 </filter>38 39 <filter-mapping>40 41 <filter-name>struts2</filter-name>42 43 <url-pattern>*.do</url-pattern>44 45 <url-pattern>*.jsp</url-pattern>46 47 </filter-mapping>

View Code

OpenSessionInViewFilter过滤器实现的原理:

  1:事务提交:spring提供的声明式事务控制,仍然在业务层的方法进行处理,方法执行完毕后,事务会自动提交,如果出现异常,事务就会回滚。但是它延迟了Session关闭的时间。

  2Session关闭:Session在页面上进行关闭,此时当页面上的数据加载完成之后,再关闭Session

问题:

  如果你开发的系统对页面数据加载比较大的时候,不适合使用OpenSessionInViewFilter,这样Session不能及时关闭,另一个Session就无法访问,连接不够使用,就会产生“假死”现象。