正常我们在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. ES常见名词定义

    集群:具有相同clusterName的节点.节点:一个ES实例,并不定是一个节点,因为一个节点上可以启动多个ES实例.索引:相当于数据库database的概念,一个集群可以包含多个索引.分片:索引可以 ...

  2. New Concept English there (7)

    27w/m Has it ever happened to you? Have you ever put your trousers in the washing machine and then r ...

  3. Python中常用的内值方法

    1)min(2,4)            ## 求最小值        2)max(2,4)            ## 求最大值3)sum(range(1,100,2)) ## 求和4)枚举:返回 ...

  4. 强化学习使用pygame模块的安装

    当你正想运行强化学习的游戏时,突然提示没有安装pygame模块怎么办呢? 其实很简单,通过下面的命令,就可以安装: D:\AI\sample\tensorforce>pip install py ...

  5. Java8安装配置

    方法1.命令行安装 -jdk 存在多个版本,自动配置: sudo update-alternatives --config java 方法2.下载安装 下载java8的jdk http://www.o ...

  6. BGP选路原则

    bgp选路原则 1 最高有weight优先,默认为0(思科特有,选大的) 2 本地优先级高的优先(只可以在IBGP邻居之间传递) 3 起源本路由器上的路由(network.aggregate-addr ...

  7. BZOJ3196 Tyvj1730 二逼平衡树 【树套树】 【线段树套treap】

    BZOJ3196 Tyvj1730 二逼平衡树 Description 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 1.查询k在区间内的排名 2.查询区间内排名 ...

  8. hbase单机及集群安装配置,整合到hadoop

    问题导读:1.配置的是谁的目录conf/hbase-site.xml,如何配置hbase.rootdir2.如何启动hbase?3.如何进入hbase shell?4.ssh如何达到互通?5.不安装N ...

  9. java集成WebSocket向所有用户发送消息

    package com.reading.controller.library; import org.springframework.stereotype.Controller; import org ...

  10. Web API的发布问题

    配置“ISAPI 和 CGI 限制”的4.0版本设置为允许,要不然出现“由于 Web 服务器上的“ISAPI 和 CGI 限制”列表设置,无法提供您请求的页面.”的错误. “An error has ...