1. 程式人生 > >spring,hiberante之*** is not valid without active transaction

spring,hiberante之*** is not valid without active transaction

Spring 3.x 與Hibernate 4.x 整合遇到的問題,描述如下:

對資料庫的 增加、刪除、修改 操作需要Spring的事務支援,所以對service層的上述操作增加事務。applicationContext.xml配置如下:

<tx:advice id="txAdvice" transaction-manager="transactionManager"> 
<tx:attributes> 
<tx:method name="add*" propagation="REQUIRED" read-only="false"/>
<tx:method name="save*" propagation="REQUIRED" read-only="false" />
<tx:method name="remove*" propagation="REQUIRED" read-only="false" />
<tx:method name="delete*" propagation="REQUIRED" read-only="false"/>
<tx:method name="modify*" propagation="REQUIRED" read-only="false"/>
<tx:method name="update*" propagation="REQUIRED" read-only="false" />
<tx:method name="*" propagation="SUPPORTS" read-only="true" /> 
</tx:attributes> 
</tx:advice>

由於Spring 3.x 對 Hibernate 4.x 不提供 HibernateDaoSupport,所以在dao的實現層注入SessionFactory,從而通過

Session session = sessionFactory.getCurrentSession();

來獲得當前的session。applicationContext.xm中 sessionFactory的HibernateProperties增加以下屬性:

<prop key="hibernate.current_session_context_class">org.springframework.orm.hibernate4.SpringSessionContext</prop>

注意:和Spring2.x不同,不能為thread,否則報錯:org.hibernate.HibernateException: save is not valid without active transaction

OK,以上配置在 增加、刪除、修改 操作時,都能正確執行,事務也正常執行!

當執行 查詢 操作時,不需要事務的支援,程式碼如下:

public List<Student> getStudentList(String str)
{
  Session session = sessionFactory.getCurrentSession();
  List<Student> list = null;
  list = session.createQuery(str).list();
  return list;
}

問題來了,報錯:org.hibernate.HibernateException: No Session found for current thread

問題解決:幾乎所有正常的操作都必須在transcation.isActive()條件下才能執行。get,load,save, saveOrUpdate,list都屬於這類!

詳情可以檢視原始碼!

建議:當方法不需要事務支援的時候,使用 Session session = sessionFactory.openSession()來獲得Session物件,問題解決!