正常我们在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. JVM的理解

    1.Java程序是交由JVM执行的,所以我们在谈Java内存区域划分的时候事实上是指JVM内存区域划分.在讨论JVM内存区域划分之前,先来看一下Java程序具体执行的过程: 也相当与 注:JVM(ja ...

  2. Swift 保存pdf并在webview显示

    本例中服务器返回的是base64 字符串,也可以直接返回byte[],看server接口的定义 let nsData = NSData(base64Encoded: data!!) 拿到nsData以 ...

  3. UNIX 环境高级编程 文件和目录

    函数stat , fstat , fstatat , lstat stat函数返回与此文件有关的信息结构. fstat函数使用已打开的文件描述符(而stat则使用文件名) fstatat函数 为一个相 ...

  4. 很让人受教的提高php代码质量的方法

    1.不要使用相对路径 常常会看到: require_once('../../lib/some_class.php'); 该方法有很多缺点: 它首先查找指定的php包含路径, 然后查找当前目录. 因此会 ...

  5. NSLayoutConstraint 布局,配合简单的动画效果

    demo地址 :链接: http://pan.baidu.com/s/1c00ipDQ 密码: mi4c 1 @interface ViewController () @property (nonat ...

  6. 考研系列 HDU2241之早起看书 三分

    考研并不是说说就可以了,要付诸于行动. 对于Lele来说,最痛苦的事莫过于早起看书了,不过为了考研,也就豁出去了.由于早起看书会对看书效率产生影响,所以对于要什么时候起床看书,还是有必要考虑的. 经过 ...

  7. LOJ2360. 「NOIP2016」换教室【概率DP】【Floyed】【傻逼题】

    LINK 思路 先floyed出两点最短路 然后就可以直接\(dp_{i,j,0/1}\)表示前i节课选择换j节,换不换当前这一节的最小贡献 直接可以枚举上一次决策的状态计算概率进行统计就可以了 我变 ...

  8. python(七):元类与抽象基类

    一.实例创建 在创建实例时,调用__new__方法和__init__方法,这两个方法在没有定义时,是自动调用了object来实现的.python3默认创建的类是继承了object. class A(o ...

  9. SpringBoot @ConfigurationProperties报错

    idea报错如下: Not registered via @EnableConfigurationProperties or marked as Spring component less... (C ...

  10. 《DSP using MATLAB》示例Example 8.18

    代码: %% ------------------------------------------------------------------------ %% Output Info about ...