hibernate的OpenSessionInView--MVC模式下hibernate关联查询还未使用数据session就关闭了导致关联查询报错的问题...

 

在开发中,我们使用hibernate进行数据的查询,当我们使用关联查询的时候,我们希望查询这个对象及这个对象包含的所有子对象,同时显示在页面中,但是当我们在页面使用的时候,会提示我们session已经关闭的异常。

 

 

在单向关联的父子对象中,如果我们需要在查询的时候,也把子对象查询出来,那么,可以设置  lazy=false

 

因为在hibernate3中,lazy的默认值是true的。如果我们不关闭懒加载,那么这个懒加载就是启用的。

 

而我们进行关联查询的时候,如果页面对一个action进行请求,那么我们进行查询:

 

 

String sql="from Article where periodicalId='"+ periodicalId+"' order by periodicalId desc,  articleDate desc ";

 

其中 Article中有一个子对象Periodical

 

我们希望的是,在查询Article的时候,把他的periodical对象也查询得到。

 

       Session session=this.getHibernateTemplate().getSessionFactory().openSession();

       List queryArticleList=session.createQuery(sql).list();

  

如果代码仅仅这样写,我们是可以查询article的子对象的。

 

但是别忘了,我们的session还没有关闭,我们需要加上:

 

 

session.close();

 

我们可以通过使用:session.isOpen() 方法来查看session是否关闭。

 

    public List queryArticleByCondition(String sql) {

       Session session=this.getHibernateTemplate().getSessionFactory().openSession();

       System.out.println("session: "+session.isOpen()+"   : ");

       List queryArticleList=session.createQuery(sql).list();

       session.close();

       System.out.println("session: "+session.isOpen()+"   : ");

       return queryArticleList;

    }

 

 

 

 

 

这样的话,如果我们在没有设置lazy的时候,就无法查询到子对象了。

 

因为此时lazytrue,也就是我们启动了懒加载,何为懒加载,懒加载就是当你需要子对象的时候,我再去进行查询,如果你不需要,我就不会去查询你的子对象的。

 

我们此时的lazytrue,那么就是说,在查询Article的时候,我只发出了一条查询,然后就把结果集List返回到service,到action,到前台页面中了,那么此时我们的页面中还需要这个Article这个对象的子对象的,所以,就会去进行加载了,就去再次进行查询这个对象的子对象,但是此时就有问题了,我们的session在我们查询完Article的时候就已经关闭了,session都已经关闭了,怎么可能会查询得到呢。所以就无法查询到子对象信息了。

 

 

 

为了解决这个问题。我们可以把lazy手动的设置为false

 

<many-to-one name="periodical" class="com.slfd.hydroElectric.entity.Periodical" column="periodicalId" not-null="true" lazy="false"/>

  

 

这样在查询article的时候,就会直接把父对象的子对象都直接查询出来,放在返回的结果集中,然后我们就可以直接使用了。

 

 

当然,我们也可以在获得session的时候,不重新打开session,而是使用当前的session

 

 

    public List queryArticleByCondition(String sql) {

       Session session=this.getHibernateTemplate().getSessionFactory().getCurrentSession();

       System.out.println("session: "+session.isOpen()+"   : ");

       List queryArticleList=session.createQuery(sql).list();

       System.out.println("session: "+session.isOpen()+"   : ");

       return queryArticleList;

    }

 

注意:我们使用getCurrentSession(); 的时候,这个时候的session是不需要我们关闭的。

这样在设置了懒加载为关闭(lazy="false")的状态之后,也是可以立即查询到子对象的数据的。

 

 

 

但是,当我们页面中的很多数据都是不立即需要,或者根据用户的操作才看是否需要的时候,我们很有可能需要设置lazy=true,那么上面的方法就无法解决这个问题了。

 

此时我们也可以通过:OpenSessionInView 来解决这个问题:

 

OpenSessionInViewSpring提供的一个针对Hibernate的一个支持类,其主要意思是在发起一个页面请求时打开HibernateSession,一直保持这个Session,直到这个请求结束。

 

它有两种使用方式:分别是OpenSessionInViewInterceptorOpenSessionInViewFilter,即一个是拦截器,一个是过滤器。

 

具体配置见网络上的文档:

 

OpenSessionInView介绍:

http://baike.baidu.com/link?url=CChyrgUcZmwjqLw_nI3IWFklts91zzVXb7x1juHc7ZksORmbCuvUUjgK3KFkHiJjrsIrWqkpDfWm8GoJSfsd_q

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值