spring3.* + hibernate3.* 整合常見問題總結
1、為了解決應用中的中文亂碼問題,我們可以不用自己開發過濾器類,Spring為我們提供了一個,只需要配置一下即可:
<!-- 解決亂碼問題 --> <filter> <filter-name>CharacterFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>CharacterFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
該類的繼承結構如下
該類如下
public class CharacterEncodingFilter extends OncePerRequestFilter {
private String encoding;
private boolean forceEncoding = false;
public void setEncoding(String encoding) { this.encoding = encoding; }
public void setForceEncoding(boolean forceEncoding) { this.forceEncoding = forceEncoding; }
@Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
if (this.encoding != null && (this.forceEncoding || request.getCharacterEncoding() == null))
{ request.setCharacterEncoding(this.encoding); if (this.forceEncoding)
{ response.setCharacterEncoding(this.encoding); } } filterChain.doFilter(request, response); }
}
2、為了解決hibernate延遲載入的問題,使用Spring中提供的過濾器來解決,它能夠讓Session
在請求解釋完成之後再關閉,配置方式如下:
同時解決Turn your Session into FlushMode.COMMIT/AUTO or remove 'readOnly' marker from
org.springframework.dao.InvalidDataAccessApiUsageException: Write operations are not allowed in read-only mode (FlushMode.NEVER/MANUAL): Turn your Session into FlushMode.COMMIT/AUTO or remove 'readOnly' marker from transaction definition. 問題:只讀模式下(FlushMode.NEVER/MANUAL)寫操作不被允許:把你的Session改成FlushMode.COMMIT/AUTO或者清除事務定義中的readOnly標記。
<filter> <filter-name>OpenSessionInViewFilter</filter-name> <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class> <init-param> <param-name>sessionFactoryBeanName</param-name> <param-value>sessionFactory</param-value> </init-param> <init-param> <param-name>singleSession</param-name> <param-value>true</param-value> </init-param> <init-param> <param-name>flushMode </param-name> <param-value>AUTO</param-value> </init-param> </filter>
該過濾器並不需要如下配置--> 配置之後就會出現刪除或者修改不執行,新增,查詢能夠正常
<filter-mapping> <filter-name>OpenSessionInViewFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
3、因為OpenSessionInViewFilter在getSession的時候,會把獲取回來的session的flush mode 設為FlushMode.NEVER。故進行insert、 update和delete操作時會產生異常:org.springframework.dao.InvalidDataAccessApiUsageException: Write operations are not allowed in read-only mode (FlushMode.NEVER/MANUAL): Turn your Session into FlushMode.COMMIT/AUTO or remove 'readOnly' marker from transaction definition. 因此需要採用spring的事務宣告,使方法受transaction控制:
<!-- 配置Spring的事務處理 --> <!-- 建立事務管理器--> <bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory" /> </bean>
<!-- 配置事務管理器應用的範圍 -->
<!-- 配置AOP,Spring是通過AOP來進行事務管理的 --> <aop:config> <!-- 設定pointCut表示哪些方法要加入事務處理 --> <!-- 以下的事務是宣告在DAO中,但是通常都會在Service來處理多個業務物件邏輯的關係,注入刪除,更新等,此時如果在執行了一個步驟之後丟擲異常 就會導致資料不完整,所以事務不應該在DAO層處理,而應該在service,這也就是Spring所提供的一個非常方便的工具,宣告式事務 --> <aop:pointcut id="allMethods" expression="execution(* com.zhao.user.service.*.*(..))" /> <!-- 通過advisor來確定具體要加入事務控制的方法 --> <aop:advisor advice-ref="txAdvice" pointcut-ref="allMethods" /> </aop:config>
<!-- 配置Advice(事務的傳播特性) 即:配置哪些方法要加入事務控制 -->
<tx:advice id="txAdvice" transaction-manager="txManager"> <tx:attributes> <!-- 讓所有的方法都加入事務管理,為了提高效率,可以把一些查詢之類的方法設定為只讀的事務 --> <tx:method name="*" propagation="REQUIRED" read-only="true"/> <!-- 以下方法都是可能設計修改的方法,就無法設定為只讀 --> <tx:method name="add*" propagation="REQUIRED"/> <tx:method name="del*" propagation="REQUIRED"/> <tx:method name="update*" propagation="REQUIRED"/> <tx:method name="save*" propagation="REQUIRED"/> </tx:attributes> </tx:advice>
4、部署應用程式,啟動伺服器,如果發現異常: java.lang.NoSuchMethodError: org.objectweb.asm.ClassVisitor.visit(IILjava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)V
這是由於整合時Jar包的衝突引起的。應將"Web應用程式/WEB-INF/lib/asm-2.2.3.jar"刪除即可。