• 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.xml中,添加lazy=”false”,查询用户的同时,立即检索查询用户关联的角色集合:

     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.xml中添加过多的lazy=false,这样如果表关联比较多,不需要查询的对象也被加载了,性能会出现问题。

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

    在web.xml中添加:

    要求:该过滤器一定要放置到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.OpenSessionInViewFilter
    10 
    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.StrutsPrepareAndExecuteFilter
    34 
    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就无法访问,连接不够使用,就会产生“假死”现象。

  • 相关阅读:
    【Spring-Security】Re01 入门上手
    【JDBC】Extra03 PostgreSQL-JDBC
    【JDBC】Extra02 SqlServer-JDBC
    【JDBC】Extra01 Oracle-JDBC
    【Oracle】Windiws-11G 安装
    【Hibernate】Re08 加载策略配置
    【Hibernate】Re07 关系映射处理
    【Hibernate】Re01.6 HQL
    【Hibernate】Re01.5 API
    【Quartz】
  • 原文地址:https://www.cnblogs.com/fuyiming/p/5774769.html
Copyright © 2020-2023  润新知