您的位置:首页 > 运维架构

OpenSessionInViewFilter解决Hibernate懒加载异常

2016-07-14 21:01 441 查看
 

          OpenSessionInViewFilter解决Hibernate懒加载异常

 

 

 

 

Hiberante懒加载特性

 

 

懒加载的目的:为了减少与数据库的交互,从而提高执行效率。

 

       在Hibernate中,查询方法有两个,分别是get()和load(),这两种方法的不同就是load()拥有懒加载的特性。Load()方法就是在查询某一条数据的时候并不会直接将这条数据以指定对象的形式来返回,而是在你真正需要使用该对象里面的一些属性的时候才会去数据库访问并得到数据。他的好处就是可以减少程序本身因为与数据库频繁的交互造成的处理速度缓慢。

 

以一个Person类做例子,我们写一个查询的方法如下

 

public static void queryInfo(int id){
Session session=null;
try{
session=HibernateUtil.getSession();
Person person=(Person) session.load(Person.class, id);
//System.out.println(person.getName());
}catch(HibernateExceptionex){
ex.printStackTrace();
}finally{
if(session!=null){
session.close();
}
}
}


 

为了方便测试,在Hibernate配置文件中添加以下属性

 

<span style="font-size:18px;"><property name="hibernate.show_sql">true</property> </span>


这条属性的作用为将Hibernate运行时产生的每一条SQL语句都打印出来

 

        运行上述方法后,我们并没有看到Hibernate打印任何查询语句,这时我们可以将注释的语句重新调回来,让他打印查询到的person的name。这时我们可以看到Hibernate产生的查询语句并看到person的name属性。这就是懒加载了。

 

        那么在Hibernate懒加载的时候,返回的对象是空的吗?答案是否定的,我们可以通过打印person.getClass()方法来验证,打印出来的结果并不是null,而是一个Person后面加了一堆很奇怪的字符的类。可以肯定的是懒加载的对象并不是空,而且这个对象的类型不是Person类。那么他到底是什么呢?

 

       其实这个兑现我们管它叫做代理对象,而这个对象所属的类是Person类的子类,是Hibernate自动实现的一个子类。这个子类的特点是:当你访问person对象的某一个属性的时候,他会自动查询数据库中对应这个对象的数据并返回,这就是为什么在创建对象关系映射的时候要求实体类不能够为final类型的原因了。

 

 

但是这个对象是有一个生命周期的,我们可以改写上述方法如下

 

public static Person queryInfo(int id){
Session session=null;
Person person=null;
try{
session=HibernateUtil.getSession();
person=(Person)session.load(Person.class, id);
//System.out.println(person.getName());
}catch(HibernateExceptionex){
ex.printStackTrace();
}finally{
if(session!=null){
session.close();
}
}
return person;
}


调用这个方法并返回查询到的代理对象,我们可以在返回该对象后打印该对象的name属性,这时会抛出一个org.hibernate.LazyInitializationException异常。

 

 

懒加载解决方案

 

       对这种懒加载问题,最后的做法是利用Spring提供的一个针对Hibernate的一个支持类,其主要意思是在发起一个页面请求时打开Hibernate的Session,一直保持这个Session,使得Hibernate的Session的生命周期变长,直到这个请求结束,具体是通过一个Filter来实现的。

 

       那么,如果现在我们想用Hibernate懒加载特性,又想用延长session的生命周期,知道将数据提到页面显示(经过action层),那么我们就得在web.xml文件中增加以下配置:

 

<!-- 配置Spring的用于解决懒加载问题的过滤器 -->
<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>*.action</url-pattern>
</filter-mapping>

 

OpenSessionInViewFilter为过滤器名字,*.action表示拦截所有的action。
注意:以上懒加载配置一定要放置在Struts2核心配置前面。

 

 

 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: