第一步,修改spring的配置文件和springmvc的配置文件
--------------------------------applicationContext.xml
<context:annotation-config/>
<context:component-scan base-package="com.xxx">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />
</context:component-scan>
--------------------------------applicationContext-mvc.xml
<context:component-scan base-package="com.xxx">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service" />
</context:component-scan>
解釋:SpringMVC配置文件產生的環境是Spring環境的子環境,會有一些沖突:SpringMVC的環境會接管Service注解,而這會使transactional失效。
所以我們要做的就是在把Service注解排除出SpringMVC環境(exclude-filter),這樣就可以讓其交給Spring環境處理了,就不會讓Transactional注解失效了;同時Spring配置中排除Controller注解,讓其交給SpringMVC環境去處理;
第二步,修改Spring配置文件中hibernate的屬性設置
在@Transactional注解的方法中,session的獲取通常是通過sessionFactory.getCurrentSession()來獲取的。而通常對應的hibernate屬性設置是如下:
<prop key="hibernate.current_session_context_class">thread</prop>
報錯中,得不到 active transaction ,通常就是這個設置錯誤。改為如下即可:
<prop key="hibernate.current_session_context_class">org.springframework.orm.hibernate4.SpringSessionContext</prop>
詳情請查看該文 如果你報createSQLQuery is not valid without active transaction,請看這里
第三步,查看是否漏掉開啟注解的配置
<tx:annotation-driven transaction-manager="txManager" />
txManager是自定義的已配置好的事務管理器。
另外,DaoImpl類上用@Repository注解,ServiceImpl類上用@Service注解。
只要注意以上三步,一般就可以解決@Transactional注解失效的問題了。
該文也可以參考 http://www.verydemo.com/demo_c143_i3007.html
PS:進一步思考,@Transactional加在@Service注解的類的方法中,就應該在springmvc配置文件中exclude-filter
如果加在@Repository注解的類中的方法中,也應該還exclude-filter org.springframework.stereotype.Repository 應該是這樣,未測試。
參考帖子:
最新SpringMVC + spring3.1.1 + hibernate4.1.0 集成及常見問題總結