博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
转载hiberinate的懒加载
阅读量:6803 次
发布时间:2019-06-26

本文共 2676 字,大约阅读时间需要 8 分钟。

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,偶现在也不知道到底是怎么个情况,有高人请指点。

转载于:https://www.cnblogs.com/jeremy-blog/p/4401837.html

你可能感兴趣的文章
Making your C++ code robust<three>
查看>>
jfreechart Line多个曲线图,曲线点图
查看>>
Ubuntu 16.04 设置固定IP地址
查看>>
资源合作推广方法
查看>>
利用vim多行注释和多行删除命令配置nginx.conf文件
查看>>
2014还是选择重新开始
查看>>
Dubbo架构设计详解
查看>>
php提取字符串中的数字
查看>>
JavaScript之函数
查看>>
azkaban3.x web-server之 jobsummary插件安装
查看>>
微软云IaaS&PaaS大比较
查看>>
redis + mysql应该如何架构?
查看>>
容器 - Map的遍历方法
查看>>
介绍一开源在线视频会议平台BigBlueButton
查看>>
sublime_text配置php调试环境
查看>>
如何在域账户下使用管理员账号安装共享打印机
查看>>
戏说守护、僵尸、孤儿进程
查看>>
表单提交时候后台数据乱码
查看>>
angular.js使用路由时,子控制器监听不到父级$boardcast的事件
查看>>
加入域的计算机登录域出现指定域的名称或安全标识(SID)与该域的信认信息不一致。...
查看>>