首页 > 代码库 > 延迟加载和session关闭的矛盾

延迟加载和session关闭的矛盾

延迟加载(no session or session was closed)就是并不是在读取的时候就把数据加载进来,而是等到使用时再加载。

    那么Hibernate是怎么知道用户在什么时候使用数据了呢?又是如何加载数据呢?

    其实很简单,它使用了代理机制。返回给用户的并不是实体本身,而是实体对象的代理。代理对象在用户调用getter方法时就会去数据库加载数据。

    但加载数据就需要数据库连接。而当我们把会话关闭时,数据库连接就同时关闭了。这种情况就叫做未初始化的关系。

    延迟加载与session关闭的矛盾一般可以这样处理:

1.使用迫切加载:

  FetchType.EAGER:加载一个实体时,定义急加载的属性会立即从数据库中加载。

2.在 session 关闭之前先获取需要查询的数据(Hibernate.initialize()方法)。

3.使用拦截器(Interceptor)或过滤器(Filter)控制 Session。

  例如:

  1. <!-- Spring的OpenSessionInView实现 -->  
  2. <filter>  
  3.     <filter-name>openSessionInViewFilter</filter-name>  
  4.     <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter  
  5.     </filter-class>  
  6. <!-- singleSession默认为true,若设为false则等于没用OpenSessionInView 。所以默认可以不写-->  
  7.      <init-param>  
  8.        <param-name>singleSession</param-name>  
  9.        <param-value>true</param-value>   
  10.      </init-param>   
  11. <!--   
  12. 指定org.springframework.orm.hibernate3.LocalSessionFactoryBean在spring配置文件中的名称,默认值为sessionFactory。 如果LocalSessionFactoryBean在spring中的名称不是sessionFactory,该参数一定要指定,否则会出现找不到sessionFactory的例外。所以默认可以不写  
  13. -->  
  14.  <init-param>  
  15.      <param-name>sessionFactoryBean</param-name>  
  16.    <param-value>sessionFactory</param-value>  
  17.   </init-param>   
  18. </filter>  
  19. <filter-mapping>  
  20.     <filter-name>openSessionInViewFilter</filter-name>  
  21.     <url-pattern>/*</url-pattern>  
  22. </filter-mapping>  

 

延迟加载和session关闭的矛盾