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物件,問題解決!