正常我们在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. SSH服务:packet_write_wait: Connection to 67.218.143.160 port 22: Broken pipe错误处理

    1.在~/.ssh/config配置文件中添加 IPQoS lowdelay throughput 2.在/etc/ssh/ssh_config配置文件中添加 IPQoS lowdelay throu ...

  2. DataTable和实体类通过反射相互转换

    using System.Runtime.Serialization; using System.Data; using System.Reflection; using System.Collect ...

  3. 【跟着stackoverflow学Pandas】add one row in a pandas.DataFrame -DataFrame添加行

    最近做一个系列博客,跟着stackoverflow学Pandas. 以 pandas作为关键词,在stackoverflow中进行搜索,随后安照 votes 数目进行排序: https://stack ...

  4. 使用fill_n算法

    今天使用这个算法来给一个数组赋值,所以把它的使用过程记录下来: fill_n函数的作用是:给你一个起始点,然后再给你一个数值count和val.把从起始点开始依次赋予count个元素val的值. 注意 ...

  5. CS231n课程笔记翻译1:Python Numpy教程

    译者注:本文智能单元首发,翻译自斯坦福CS231n课程笔记Python Numpy Tutorial,由课程教师Andrej Karpathy授权进行翻译.本篇教程由杜客翻译完成,Flood Sung ...

  6. Hello Pythoner!

    首先,欢迎你来到pyer的博客,希望你能有所收获! 然后,pyer之前学C#(原博客地址:初行-博客园),后来转的Python,目前从事服务端研发工作. 最后,相逢便是缘,如果看过pyer的博客后有什 ...

  7. Hadoop2.x下安装HBase

    1.安装好 hadoop 集群,并启动 [grid@hadoop4 ~]$ /sbin/start-dfs.sh [grid@hadoop4 ~]$ /sbin/start-yarn.sh 查看 ha ...

  8. 如何最快速地将旧的 NuGet 包 (2.x, packages.config) 升级成新的 NuGet 包 (4.x, PackageReference)

    最近我将项目格式进行了升级,从旧的 csproj 升级成了新的 csproj:NuGet 包管理的方式也从 packages.config 升级成了 PackageReference.然而迁移完才发现 ...

  9. WebLogic11g-创建域(Domain)及基本配置

    转:http://www.codeweblog.com/weblogic11g-%e5%88%9b%e5%bb%ba%e5%9f%9f-domain-%e5%8f%8a%e5%9f%ba%e6%9c% ...

  10. 微信小程序(3)——常用的组件

    view: view是小程序中的视图容器之一,似于html中的<div>标签 <view class="section"> <view class=& ...