在开发中,我们使用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的时候,就无法查询到子对象了。
因为此时lazy是true,也就是我们启动了懒加载,何为懒加载,懒加载就是当你需要子对象的时候,我再去进行查询,如果你不需要,我就不会去查询你的子对象的。
我们此时的lazy为true,那么就是说,在查询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 来解决这个问题:
OpenSessionInView是Spring提供的一个针对Hibernate的一个支持类,其主要意思是在发起一个页面请求时打开Hibernate的Session,一直保持这个Session,直到这个请求结束。
它有两种使用方式:分别是OpenSessionInViewInterceptor和OpenSessionInViewFilter,即一个是拦截器,一个是过滤器。
具体配置见网络上的文档:
OpenSessionInView介绍:
相关推荐
介绍Spring+hibernate opensessioninview问题
为了练手培训,给大家准备的 Open Session In View 的简单例子,纯代码,大家可以参考,其中主要说了六部分内容: 1.通过接口编程 2.通过spring注入dao到 action 3.通过 open session in view filter 支持 延迟加载...
在没有使用Spring提供的Open Session In View情况下,因需要在service(or Dao)层里把session关闭,所以lazy loading 为true的话,要在应用层内把关系集合都初始化,如 company.getEmployees(),否则Hibernate抛...
2,但在加载时,如果Session已经关掉了就会抛LazyInitializationException异常 二,集成 Spring 与 Struts2.1.8.1 1,在web.xml配置监听器(Spring Reference 15.2 Common configuration) <!-- 集成Spring -...
NULL 博文链接:https://likenice.iteye.com/blog/290162
OpenSessionInView项目整合jar包
NULL 博文链接:https://8366.iteye.com/blog/472141
最新版SSH项目整合 实现了OpenSessionInView。 hibernate5.2.3+struts2.5.2+spring4.3.3
SSH项目整合示例【OpenSessionInView】所用到的jar包 包含Struts + Hibernate + Spring所有jar及其依赖的jar
Spring提供的CharacterEncoding和OpenSessionInView功能
和Spring中OpenSessionInView由于org.springframework.web.struts.ContextLoaderPlugIn中保存同一个对象的名不同导致openSessionInView失效 稍微修改后在struts-config.xml中使用MyContextLoaderPlugIn.jar包中...
spring2.5学习PPT 传智博客 01_全面阐释Spring及其各项功能 ... 30.Spring提供的CharacterEncoding和OpenSessionInView功能 31.使用Spring集成JPA 32.Struts+Spring+JPA集成 33.使用Spring集成Struts2 34.所有源码
NULL 博文链接:https://yanzhenwei.iteye.com/blog/1701164
使用 AOC 拦截器而不是过滤器进行 OpenSessionInView 处理 列出一个国家的城市和添加城市的可能性(bean 验证和自动检索 lat 和 lng 坐标) 安全 安全的 REST Web 服务 使用 CSRF 令牌 角度父状态的问题 有用的链接 ...
SSH项目整合示例【OpenSessionInView】源码
Spring的Ioc Spring的AOP , AspectJ Spring的事务管理 , 三大框架的整合 目录 1.1 Spring 框架学习路线:..........................................................................................................