解决多线程下使用懒加载时,可能会出现的could not initialize proxy - no Session问题

这里使用的框架是spring、jpa和hibernate的整合,针对一个请求中扩大session的范围可参考这个做法,在web.xml配置文件加入,主要要在核心过滤器前面,这里加的过滤器是openEntityManagerInViewFilter,因为使用的是spring jpa的session会话:

<!-- 解决懒加载 no session(会话无效)问题 -->
  <filter>
    <filter-name>openEntityManagerInViewFilter</filter-name>
    <filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>openEntityManagerInViewFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

至于多线程下,通过扩大session范围来也无法解决时,则可在线程启动的run方法中绑定JPA EntityManager的session,才能保证能在新的线程中使用事务和延迟加载等功能,这里报错应该是请求发起,开多个线程,线程在异步执行,这时请求已经完成,session关闭,那多线程下再获取之前的懒加载数据就会报错提示no Session,解决代码参考如下:

//先在需要使用的类通过注解的方式或其他方式注入获取JPA实体管理器工厂,再传入线程
@PersistenceUnit
private EntityManagerFactory emFactory;


//例如:打开线程进行处理,传入工厂
Thread thread = new Thread(emFactory);
thread.start();
//在启动线程的run方法绑定session会话
public void run(){
    //在线程中添加数据库Session
	boolean participate = false;
    if (TransactionSynchronizationManager.hasResource(emFactory)) {
		participate = true;
	}else{
		try {
			EntityManager em = emFactory.createEntityManager();
			EntityManagerHolder emHolder = new EntityManagerHolder(em);
			TransactionSynchronizationManager.bindResource(emFactory, emHolder);
		}
		catch (PersistenceException ex) {
			throw new DataAccessResourceFailureException("Could not create JPA         
            EntityManager at Thread", ex);
		}
	}


    //---------------------------------------
    //你的业务代码
    //-----------------------------------------

    //如果添加过数据库Session,在结束时关闭Session
	if(!participate){
		EntityManagerHolder emHolder = (EntityManagerHolder)
		TransactionSynchronizationManager.unbindResource(emFactory);		 
        EntityManagerFactoryUtils.closeEntityManager(emHolder.getEntityManager());
	}
}

 

  • 6
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值