在开发电子化自动支付的开关功能过程中,遇到了一个很有意思的问题,no session for current thread,查找资料,这句话的大概意思是说当前线程不存在会话管理,查找代码配置文件,采用的事务管理是通过注解的方式进行配置管理,而且项目是已经生产运行了很久,不存在不管理事务的情况,那么唯一的情况,就是自己调用的数据库查询方法有误了。
我们看一下事务配置管理文件:
排除了这个问题,那么可能就是自己调用的dao接口错误了,我们看一下出错的这段代码逻辑(由于就新增了一段代码,很容易就确定问题出在哪,不需要dubug模式确定问题根源了):
// 授权支付失败 退还额度
boolean isUseNewStandard = false;
String hql = " from AdmdivCode a where a.moneyCorpCode='Y' and a.admdivCode='" + ecfnPay.getAdmDivCode() + "'";
List<AdmdivCode> adCodes = publicDao.find(hql);
if (adCodes != null && adCodes.size()> 0) {
isUseNewStandard = true;
}
可以确定的是,就是这段代码(查询)的地方报错,那么,我们看下dao接口:
public interface PublicDao<T> {
public List<T> find(String hql);
public List find_SS(String hql);
}
public class PublicDaoImpl implements PublicDao {
@Override
public List find(String hql) {
return this.getCurrentSession().createQuery(hql).list();
}
@Override
public List find_SS(String hql) {
Session ss = sessionFactory.openSession();
Transaction ts = ss.beginTransaction();
List datas = null;
try {
datas = ss.createQuery(hql).list();
ts.commit();
} catch (HibernateException e) {
ts.rollback();
e.printStackTrace();
throw e;
} finally {
ss.close();
}
return datas;
}
}
Hibernate与spring集成之后,如果需要获取session,并且使用getCurrentSession(),就会报这个错:“No Session found for current thread”。我们看一下代码,我们的确用的是find()而非find_SS(),查看其实现,就知道这个错误的原因了,改下调用方法,问题解决。
我们程序采用配置TranactionManager的方式进行事务管理,并且通过申明的方式引入事务(@Service),这里也可以通过@Transactional的方式,配置完毕,Spring会在开始事务之前通过AOP的方式为当前线程创建Session,此时调用getCurrentSession()将得到正确结果。
由于实现方法中,find_SS()已经自己开启session,所以我们调用find_SS即可,若无该方法,我们可以按照如上的方式进行解决。