关于Hibernate的lazy load以及OpenSessionInView

HIBERNATE的持久化对象加载策略。
延迟加载, 也就是用到的时候才去加载.这样可以提高一些性能.
Hibernate的lazy loading 采用了一个HibernateSession来管理session,它的逻辑是每进行一次数据库操作,就开新的session,操作完成后立即关闭该session。这样做的好处是可以严格关闭session,避免菜鸟级的错误,但是hibernate.org并不推荐这么做。因为这不适合lazy loading,也不适合跨方法的事务。

比如在我们的应用中,user->post形成一对多的映射,User中有一个包含post的List。
在User中,有多个属性:name,password,phone等,还有一个List类型的posts。当我们对posts使用lazy laoding的时候,hibernate会在获得User对象的时候,仅仅返回name,password,phone等基本属性,当你访问posts的时候,它才会从数据库中提取posts需要的数据,这就是所谓lazy laoding。但是在我们的系统中,session是被立即关闭的,也就是在读取了name,password,phone等基本属性后,session已经close了,再进行lazy loaiding就会有异常。
解决办法是在close session之前,调用Hibernate.initialize(user.getPosts()),告诉系统,user.getPosts()是需要lazy laoding的。但是这样做会破坏HibernateSession类的封装.


后来采用所谓的OpenSessionInView模式,把session的周期交给servlet filter来管理,每当有request进来,就打开一个session,response结束之后再关闭它,这样可以让session存在于整个请求周期中。


OpenSessionInViewFilter是Spring提供的一个针对Hibernate的一个支持类,其主要意思是在发起一个页面请求时打开 Hibernate的Session,一直保持这个Session,直到这个请求结束,具体是通过一个Filter来实现的。

  由于Hibernate引入了Lazy Load特性,使得脱离Hibernate的Session周期的对象如果再想通过getter方法取到其关联对象的值,Hibernate会抛出一个 LazyLoad的Exception。所以为了解决这个问题,Spring引入了这个Filter,使得Hibernate的Session的生命周期变长。
  有两种方式可以配置实现OpenSessionInView,分别是 OpenSessionInViewInterceptor和OpenSessionInViewFilter,功能完全相同,只不过一个在 web.xml配置,另一个在application.xml配置而已。我个人比较倾向配置在application.xml里,因为web.xml里配置的东西的太多的话容易发生冲突,虽然可以调整,但是毕竟多了个麻烦。

以下是OpenSessionInViewInterceptor配置

view plaincopy to clipboardprint?
<beans> 
  <bean name="openSessionInViewInterceptor" class="org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor"> 
  <property name="sessionFactory"> 
  <ref bean="sessionFactory"/> 
  </property> 
  </bean> 
  <bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> 
  <property name="interceptors"> 
  <list> 
  <ref bean="openSessionInViewInterceptor"/> 
  </list> 
  </property> 
  <property name="mappings"> 
  ......  
  </property> 
  </bean> 
  ......  
  </beans>  
<beans>
  <bean name="openSessionInViewInterceptor" class="org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor">
  <property name="sessionFactory">
  <ref bean="sessionFactory"/>
  </property>
  </bean>
  <bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
  <property name="interceptors">
  <list>
  <ref bean="openSessionInViewInterceptor"/>
  </list>
  </property>
  <property name="mappings">
  ......
  </property>
  </bean>
  ......
  </beans> 

以下是OpenSessionInViewFilter配置:

view plaincopy to clipboardprint?
<web-app> 
  ......  
  <filter> 
  <filter-name>hibernateFilter</filter-name> 
  <filter-class> 
  org.springframework.orm.hibernate3.support.OpenSessionInViewFilter  
  </filter-class> 
  <init-param> 
  <param-name>singleSession</param-name> 
  <param-value>true</param-value> 
  </init-param> 
  </filter> 
  ......  
  <filter-mapping> 
  <filter-name>hibernateFilter</filter-name> 
  <url-pattern>*.do</url-pattern> 
  </filter-mapping> 
  ......  
  </web-app> 



本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/Jermaine/archive/2009/02/01/3857140.aspx

你可能感兴趣的:(spring,xml,Hibernate,Web,配置管理)