正常我们在web开发中,由于需要在页面上或者脱离事务时使用到懒加载对应的对象,一般都采用Open Session In View模式。
 

Open Session In View

 
OpenSessionInView 模式用法探讨,在没有使用Spring提供的Open Session In View情况下,因需要在service(or Dao)层里把session关闭,所以lazy loading 为true的话,要在应用层内把关系集合都初始化,如company.getEmployees(),否则Hibernate抛session already closed Exception。 
 
Open Session In View提供了一种简便的方法,较好地解决了lazy loading问题。它有两种配置方式OpenSessionInViewInterceptor和OpenSessionInViewFilter(具体参看SpringSide),功能相同,只是一个在web.xml配置,另一个在application.xml配置而已。 
 
Open Session In View在request把session绑定到当前thread期间一直保持hibernate session在open状态,使session在request的整个期间都可以使用,如在View层里PO也可以lazy loading数据,如 ${ company.employees }。当View 层逻辑完成后,才会通过Filter的doFilter方法或Interceptor的postHandle方法自动关闭session。
 
Hibernate中自带了OpenSessionInViewFilter,我们可以直接在web.xml中对其进行配置:
<filter>
<filter-name>openSessionInViewFilter</filter-name>
<filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class>
<init-param>
<param-name>singleSession</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>openSessionInViewFilter</filter-name>
<url-pattern>*.do</url-pattern>
</filter-mapping>
 
 
这样就可以对所有的服务请求都进行过滤,并在其中绑定了SessionFactory,具体可以查看org.springframework.orm.hibernate4.support.OpenSessionInViewFilter源码。
 
由于定时任务(Cron)并不是通过请求过来的,不会走到Filter中,所以也不会在线程上下文中绑定sessionFactory,因此需要用其他的方式。如果使用OpenSessionInViewInterceptor绑定service,就会将所有的service再次重新绑定,也没有这个必要。
 
因此,这里我们仿照OpenSessionInViewInterceptor写了一个专门绑定到指定包的Interceptor来做这件事情,确定所有的cron服务都经过sessionFactory绑定即可。
 
@Component
@Aspect
public class OpenSessionInCronInterceptor { private static final Logger logger = Logger.getLogger(OpenSessionInCronInterceptor.class.getName()); @Autowired
private SessionFactory sessionFactory; @Pointcut("execution(void com.ejiapei.service.cron.*.work())")
protected void definePointcut() {
} @Before("definePointcut()")
public void preHandle() throws DataAccessException {
logger.info("Opening Hibernate Session in OpenSessionInViewInterceptor");
Session session = openSession();
TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(session));
} /**
* Unbind the Hibernate <code>Session</code> from the thread and close it).
*
* @see org.springframework.transaction.support.TransactionSynchronizationManager
*/
@After("definePointcut()")
public void afterCompletion() throws DataAccessException {
SessionHolder sessionHolder =
(SessionHolder) TransactionSynchronizationManager.unbindResource(sessionFactory);
logger.info("Closing Hibernate Session in OpenSessionInViewInterceptor");
SessionFactoryUtils.closeSession(sessionHolder.getSession());
} /**
* Open a Session for the SessionFactory that this interceptor uses.
* <p>The default implementation delegates to the
* <code>SessionFactory.openSession</code> method and
* sets the <code>Session</code>'s flush mode to "MANUAL".
*
* @return the Session to use
* @throws org.springframework.dao.DataAccessResourceFailureException if the Session could not be created
* @see org.hibernate.FlushMode#MANUAL
*/
protected Session openSession() throws DataAccessResourceFailureException {
try {
Session session = SessionFactoryUtils.openSession(sessionFactory);
session.setFlushMode(FlushMode.MANUAL);
return session;
} catch (HibernateException ex) {
throw new DataAccessResourceFailureException("Could not open Hibernate Session", ex);
}
} }
首先,我们需要使用@Autowird从当前的Spring容器中获取到绑定的SessionFactory,用来创建Session,这部分与OpenSessionInView Filter/Interceptor的代码比较类似,只不过spring提供的这两个方式做的事情实际上比我们这里需要的还要多。
 
这样,我们就可以在开始执行定时任务之前使用绑定的SessionFactory去重新开启一个Session,并绑定至SessionHolder,也就是该线程上线文中,就避免了懒加载的问题。 
 
除此之外,还有一种比较暴力的方式,就是把所有懒加载的地方都修改成Lazy.EAGER,如果这样就改为非懒加载,但是可能会影响性能,因为影响了Hibernate访问数据库的方式。
 
 
 
 
 

Web项目中定时任务无法绑定SessionFactory的问题解决的更多相关文章

  1. 在基于MVC的Web项目中使用Web API和直接连接两种方式混合式接入

    在我之前介绍的混合式开发框架中,其界面是基于Winform的实现方式,后台使用Web API.WCF服务以及直接连接数据库的几种方式混合式接入,在Web项目中我们也可以采用这种方式实现混合式的接入方式 ...

  2. 【Filter 不登陆无法访问】web项目中写一个过滤器实现用户不登陆,直接给链接,无法进入页面的功能

    在web项目中写一个过滤器实现用户不登陆,直接给链接,无法进入页面,而重定向到登陆界面的功能. 项目是用springMVC+spring+hibernate实现 (和这个没有多大关系) 第一步: 首先 ...

  3. web项目中配置多个数据源

    web项目中配置多个数据源 spring + mybatis 多数据源配置有两种解决方案 1.配置多个不同的数据源,使用一个sessionFactory,在业务逻辑使用的时候自动切换到不同的数据源,  ...

  4. spring web项目中整合netty, akka

    spring web项目中整合netty, akka 本身的web项目仍然使用tomcat/jetty8080端口, 在org.springframework.beans.factory.Initia ...

  5. JAVA WEB项目中各种路径的获取

    JAVA WEB项目中各种路径的获取 标签: java webpath文件路径 2014-02-14 15:04 1746人阅读 评论(0) 收藏 举报  分类: JAVA开发(41)  1.可以在s ...

  6. Web 项目中分享到微博、QQ空间等分享功能

    Web 项目中分享到微博.QQ空间等分享功能 网上有很多的模板以及代码,但是有很多都不能分享内容,简单的测试了下: 以新浪微博为例,文本框中的内容是title属性,下面的链接是url属性,如果你的链接 ...

  7. java web项目中 获取resource路径下的文件路径

    public GetResource{ String path = GetResource.class.getClassLoader().getResource("xx/xx.txt&quo ...

  8. web项目中加入struts2、spring的支持,并整合两者

    Web项目中加入struts2 的支持 在lib下加入strut2的jar包 2. 在web.xml中添加配置 <filter> <filter-name>struts2< ...

  9. Java Web学习系列——Maven Web项目中集成使用Spring、MyBatis实现对MySQL的数据访问

    本篇内容还是建立在上一篇Java Web学习系列——Maven Web项目中集成使用Spring基础之上,对之前的Maven Web项目进行升级改造,实现对MySQL的数据访问. 添加依赖Jar包 这 ...

随机推荐

  1. cookie注入原理及注入检测

    通常我们的开发人员在开发过程中会特别注意到防止恶意用户进行恶意的注入操作,因此会对传入的参数进行适当的过滤,但是很多时候,由于个人对安全技术了解的不同,有些开发人员只会对get,post这种方式提交的 ...

  2. 2018-2019-2 《网络对抗技术》Exp2 后门原理与应用 20165210

    2018-2019-2 <网络对抗技术>Exp2 后门原理与应用 20165210 实验内容: 使用netcat获取主机操作Shell,cron启动. 使用Socat获取主机操作Shell ...

  3. iOS实现程序长时间未操作退出

    大部分银行客户端都有这样的需求,在用户一定时间内未操作,即认定为token失效,但未操作是任何判定的呢?我的想法是用户未进行任何touch时间,原理就是监听runloop事件.我们需要进行的操作是创建 ...

  4. css 中相对定位和绝对定位

    1. css中定位机制有三种: 标准文档流, 浮动, 绝对定位 2. 绝对定位就属于第三种定位, 用到position属性, 下面就是具体设置 相对定位: 相对于自身原有位置(就是普通流的时候)进行偏 ...

  5. js中top、self、parent

    1.在应用iframe或者frameset的时候 parent指的是父窗口.top指的是顶级的窗口.self指的是当前的窗口-window window.self 功能:是对当前窗口自身的引用.它和w ...

  6. Vim技能修炼教程(1) - 使用vundle管理插件

    世界上有两个伟大的编辑器:一个是emacs,一个是vi.它们从诞生以来,一直在Unix/Linux世界得到最广泛的支持. 尽管过了几十年,在Windows平台上和跨平台上有层出不穷的后起之秀不断挑战它 ...

  7. windows上操作git基本命令

    今天准备整理一下代码,重温一下Git的基本命令,好久不用忘得差不多了. 1. 进入某个目录: 进入D盘,然后进入D盘的名为git的文件夹: $ cd D: $ cd Git 2. 返回上一级目录: $ ...

  8. SQL基础四(例子)

    ------------------------------------------------ --分别创建student/course/score表 Create table student ( ...

  9. ubuntu16.04 LTS grafana安装与启动

    1.首先从官网上下载相应的包,网址为:http://grafana.org/download 2.安装 cd Downloads sudo dpkg -i grafana_4.1.2-14869897 ...

  10. 搭建简单Samba服务器

    本文主要实现搭建简单的Samba服务器,使得Windows能访问Linux下的共享目录,为了简单,已经关闭iptables和selinux. 1.安装samba服务器 #yum list all sa ...