在SSH框架的项目中,做数据库操作,报出如下异常:
No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here。
报错原因是在dao操作时,使用了原生的SQL语句查询,之前没有报错是因为一直用的是Hql语句,用criteria或者query对象,用HibernateTemplate操作也不报错。解决方法:
第一:配置spring中的hibernate的sessionFactory的参数:
<property name="hibernateProperties">
<props>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.dialect">
org.hibernate.dialect.MySQLDialect
</prop>
<prop key="hibernate.cache.provider_class">
org.hibernate.cache.EhCacheProvider
</prop>
<prop key="hibernate.cache.provider_configuration_file_resource_path">
ehcache.xml
</prop>
<!-- 增加-->
<prop key="hibernate.current_session_context_class">thread</prop>
</props>
</property>
红色部分为新添加的参数。原因是:
当我们用Spring管理hibernate时,会让Spring自动管理事务,这时候我们就会继承HibernateDaoSupport类,并且使用HibernateTemplate对数据库进行操作,为了能让索引文件自动更新,我想使用FullTextSession
所用调用了以下方法:
Session session = getHibernateTemplate().getSessionFactory().getCurrentSession();
FullTextSession fullTextSession = Search.createFullTextSession(session);
但是getCurrentSession()时就会报错:No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here
大概意思是session没有绑定到线程上。
第二,还有一个参数
还看到一个帖子,上面还有一个参数是:
<prop key="hibernate.transaction.factory_class">
org.hibernate.transaction.JDBCTransactionFactory
</prop>
具体作用不清楚,待学习。
第三,Session was already closed异常
当我解决了session线程绑定的异常之后,又报出session was already closed这个异常,一查得知session在事物提交的时候已经关闭了。详情如下:(网上抄袭的)
“debug跟到t.commit()代码里,发现是调用的JDBCTransaction实现类的方法. 一番找寻后终于在finally里看到了closeIfRequired方法,很是可疑!名字都起的那么”此地无银三百两”. 一番跟踪这后,在transactionContext.managedClose方法里找到了”犯罪现场”: close()! 原来已经调用此方法给关掉了!”
所以,对于session关闭之前,做如下判断:
if(session.isOpen()){
session.close();
}
最后,思考。
以上两个异常综合起来,难道用HQL语言,criteria对象进行crud操作都没有真正启用session吗?所有的session.close()方法都没用?session也没有被什么线程调用吗?
待学习。