hibernate的懒加载问题

本文介绍了在使用Hibernate框架时遇到的懒加载异常问题及其四种解决方案,包括在业务层方法中解决、初始化对象关联集合、修改XML配置文件以及使用OpenSessionInViewFilter过滤器。

产生:

当使用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关闭的时间。

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

 

问题:如果你开发的系统对页面数据加载比较大的时候,不适合使用

OpenSessionInViewFilter,这样Session不能及时关闭,另一个Session就无法访问,连接不够使用,就会产生“假死”现象。

转载于:https://www.cnblogs.com/kimi9py/p/5683238.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值