zoukankan      html  css  js  c++  java
  • 转载hiberinate的懒加载

    Hibernate的强大之处之一是懒加载功能,可以有效的降低数据库访问次数和内存使用量。但用的不好就会出现org.hibernate.LazyInitializationException。

    这个异常出现的原因很简单,主要时在加载懒数据时Session已经关闭造成的,如下图:

    那么OK,我们来考虑怎么解决吧。

    我们只要在渲染JSP之前不要关闭Session,而在JSP渲染之后再关闭就OK啊。我们知道,在JSP/Servlet中,可以配置过滤器来实现这种功能。

    我们考虑两种情况的解决方案: 单使用Hibernate和用Spring来管理Hibernate。

    1. 单使用Hibernate:

    我们可以自己写一个过滤器:

    Java代码  收藏代码
    1. import java.io.IOException;  
    2.   
    3. import javax.servlet.Filter;  
    4. import javax.servlet.FilterChain;  
    5. import javax.servlet.FilterConfig;  
    6. import javax.servlet.ServletException;  
    7. import javax.servlet.ServletRequest;  
    8. import javax.servlet.ServletResponse;  
    9.   
    10. import org.hibernate.SessionFactory;  
    11. import org.hibernate.StaleObjectStateException;  
    12. import org.sunxin.struts2.util.hibernate.HibernateUtil;  
    13.   
    14.   
    15. public class HibernateThreadFilter implements Filter  
    16. {  
    17.     private SessionFactory sf=null;  
    18.       
    19.     public void init(FilterConfig arg0) throws ServletException  
    20.     {  
    21.           
    22.         sf=HibernateUtil.getSessionFactory();  
    23.     }  
    24.   
    25.     public void doFilter(ServletRequest request, ServletResponse response,  
    26.             FilterChain chain) throws IOException, ServletException  
    27.     {  
    28.         try  
    29.         {  
    30.               
    31.             sf.getCurrentSession().beginTransaction();  
    32.               
    33.             chain.doFilter(request, response);  
    34.               
    35.             sf.getCurrentSession().getTransaction().commit();  
    36.               
    37.         }  
    38.         catch (StaleObjectStateException staleEx)  
    39.         {  
    40.             throw staleEx;  
    41.         }  
    42.         catch (Throwable ex)  
    43.         {  
    44.             ex.printStackTrace();  
    45.             try  
    46.             {  
    47.             //如果发生异常,让事务回滚。  
    48.                 if (sf.getCurrentSession().getTransaction().isActive())  
    49.                 {  
    50.                     sf.getCurrentSession().getTransaction().rollback();  
    51.                 }  
    52.             }   
    53.             catch (Throwable rbEx)  
    54.             {  
    55.                System.err.println(rbEx.toString());  
    56.             }  
    57.         }  
    58.     }  
    59.   
    60.     public void destroy(){}  
    61.   
    62. }  

    在web.xml中加入这个Filter的配置:

    Xml代码  收藏代码
    1. <filter>  
    2.     <filter-name>HibernateThreadFilter</filter-name>  
    3.     <filter-class>org.sunxin.struts2.filter.HibernateThreadFilter</filter-class>  
    4. </filter>  
    5. <filter-mapping>  
    6.     <filter-name>HibernateThreadFilter</filter-name>  
    7.     <url-pattern>/*</url-pattern>  
    8. </filter-mapping>  

     这样就在访问后台代码之前打开session,访问后台代码之后关闭session。

    2. 用Spring管理Hibernate:

    I . Spring为我们提供了这样一个过滤器,我们这样配置一下就OK。

    在web.xml中加入Filter的配置:

    Xml代码  收藏代码
    1. <filter>  
    2.     <description>处理Hibernate的懒加载问题</description>  
    3.     <filter-name>openSessionInViewFilter</filter-name>  
    4.     <filter-class>  
    5.         org.springframework.orm.hibernate3.support.OpenSessionInViewFilter  
    6.     </filter-class>  
    7.     <init-param>  
    8.         <description>  
    9.             默认情况下,这个Filter会在Spring的bean池中找一个叫做sessionFactory的bean。如果使用了其他名字的SessionFactory,则应该在这里  
    10.             指定这个名字。  
    11.         </description>  
    12.         <param-name>sessionFactoryBeanName</param-name>  
    13.         <param-value>sessionFactory</param-value>  
    14.     </init-param>  
    15.     <init-param>  
    16.         <description></description>  
    17.         <param-name>singleSession</param-name>  
    18.         <param-value>true</param-value>  
    19.     </init-param>  
    20. </filter>  

     II . 同时Spring还为我们提供了另一种方案,就是使用拦截器,但偶还不太知道怎么配的,配的没有成功。还有这里需要用到spring-mvc.jar,不在spring.jar里面。还听说这个使用这个拦截器会有一些bug,偶现在也不知道到底是怎么个情况,有高人请指点。

  • 相关阅读:
    Swift 扩展
    Swift 类型转换
    Swift 自动引用计数(ARC)
    Swift 可选链
    Swift 析构过程
    Swift 构造过程
    Swift 继承
    Swift 下标脚本
    Swift 方法
    Swift 属性
  • 原文地址:https://www.cnblogs.com/jeremy-blog/p/4401837.html
Copyright © 2011-2022 走看看