在介绍Hibernate事务配置之前仍然要先搭建SSH2环境,在前文《Spring整合Struts2中拦截链与注解的使用 》中已经介绍过了Spring与Struts2的整合,接下来我们集成Hibernate需要做的有两件事情,第一加入Hibernate依赖包,第二是在web.xml文件中进行对Hibernate的相关配置。首先来来看需要加入的Hibernate依赖包:

         1.antlr-2.7.6.jar

         2.commons-collections-3.1.jar

         3.dom4j-1.6.1.jar

         4.hibernate-jpa-2.0-api-1.0.1.Final.jar

         5.javassist-3.12.0.GA.jar

         6.jta-1.1.jar

         7.ojdbc14.jar

         8.slf4j-api-1.6.1.jar

         9.slf4j-nop-1.6.4.jar

         10.hibernate3.jar

最后需要加入的jar包是你所使用的数据库的驱动,我使用的是mysql数据库,所以加入mysql驱动包mysql-connector-java-3.1.13-bin.jar(根据你所使用的数据库加入相关驱动jar)。接下来进行各配置文件的相关配置,web.xml文件的配置,配置方式如下:


1. <?xml version="1.0" encoding="UTF-8"?>  
2. <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">  
3. <display-name>SSH2</display-name>  
4. <welcome-file-list>  
5. <welcome-file>index.html</welcome-file>  
6. <welcome-file>index.htm</welcome-file>  
7. <welcome-file>index.jsp</welcome-file>  
8. <welcome-file>default.html</welcome-file>  
9. <welcome-file>default.htm</welcome-file>  
10. <welcome-file>default.jsp</welcome-file>  
11. </welcome-file-list>  
12.     
13. <context-param>  
14. <param-name>contextConfigLocation</param-name>  
15. <param-value>classpath:config/applicationContext-*.xml</param-value>  
16. </context-param>  
17.     
18.     
19. <filter>  
20. <filter-name>characterEncoding</filter-name>  
21. <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>  
22. <init-param>  
23. <param-name>encoding</param-name>  
24. <param-value>UTF-8</param-value>  
25. </init-param>  
26. <init-param>  
27. <param-name>forceEncoding</param-name>  
28. <param-value>true</param-value>  
29. </init-param>  
30. </filter>  
31.     
32. <filter-mapping>  
33. <filter-name>characterEncoding</filter-name>  
34. <url-pattern>/*</url-pattern>  
35. </filter-mapping>  
36.     
37. <filter>  
38. <filter-name>openSession</filter-name>  
39. <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>  
40. </filter>  
41.     
42. <filter-mapping>  
43. <filter-name>openSession</filter-name>  
44. <url-pattern>/*</url-pattern>  
45. </filter-mapping>  
46.     
47. <filter>  
48. <filter-name>struts2</filter-name>  
49. <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>  
50. <init-param>  
51. <param-name>config</param-name>  
52. <param-value>struts-default.xml,struts-plugin.xml,config/struts.xml</param-value>  
53. </init-param>  
54. </filter>  
55.     
56. <filter-mapping>  
57. <filter-name>struts2</filter-name>  
58. <url-pattern>/*</url-pattern>  
59. </filter-mapping>  
60.     
61. <listener>  
62. <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  
63. </listener>  
64. </web-app>



struts.xml文件的配置内容:





1. <?xml version="1.0" encoding="UTF-8" ?>  
2. <!DOCTYPE struts PUBLIC  
3.     "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"  
4. >  
5.   
6. <struts>  
7. <constant name="struts.action.extension" value=","></constant>  
8. <package name="testregist" namespace="/" extends="struts-default">  
9. <action name="regist" class="registAction">  
10. <result name="success">/success.jsp</result>  
11. <result name="error" type="redirect">/error.jsp</result>  
12. </action>  
13. </package>  
14. </struts>



applicationContext-bean.xml文件的配置内容:



1. <?xml version="1.0" encoding="UTF-8"?>  
2. <beans xmlns="http://www.springframework.org/schema/beans"  
3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
4. xmlns:aop="http://www.springframework.org/schema/aop"  
5. xmlns:context="http://www.springframework.org/schema/context"  
6. xmlns:tx="http://www.springframework.org/schema/tx"  
7. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd  
8.         http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd  
9.         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd  
10. >  
11.       
12. <!-- Spring管理Struts2的Action -->  
13. <bean name="registAction" class="com.action.UserManagerAction" scope="prototype">  
14. <property name="userManager" ref="userManager"></property>  
15. </bean>  
16.       
17. <bean name="userManager" class="com.service.UserManager" scope="prototype">  
18. <property name="userDao" ref="userDao"></property>  
19. </bean>  
20.       
21. <bean name="userDao" class="com.dao.impl.UserDaoImpl">  
22. <property name="sessionFactory" ref="sessionFactory"></property>   
23. </bean>  
24.       
25. </beans>


applicationContext-commons文件的配置内容:


 


1. <?xml version="1.0" encoding="UTF-8"?>  
2. <beans xmlns="http://www.springframework.org/schema/beans"  
3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
4. xmlns:aop="http://www.springframework.org/schema/aop"  
5. xmlns:context="http://www.springframework.org/schema/context"  
6. xmlns:tx="http://www.springframework.org/schema/tx"  
7. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd  
8.         http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd  
9.         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd  
10. >  
11.   
12. <!-- 配置sessionFactory的方式 -->  
13.        
14. <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">  
15. <property name="configLocation">  
16. <value>classpath:config/hibernate.cfg.xml</value>  
17. </property>  
18. </bean>  
19.       
20. <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">  
21. <property name="sessionFactory" ref="sessionFactory"></property>  
22. </bean>  
23.       
24. <!-- 第一种配置事务的方式 ,tx-->  
25.     <!--    
26. <tx:advice id="txadvice" transaction-manager="transactionManager">  
27. <tx:attributes>  
28. <tx:method name="add*" propagation="REQUIRED" no-rollback-for="com.exception.MyRuntimeException"/>  
29. <tx:method name="modify*" propagation="REQUIRED" no-rollback-for="com.exception.MyRuntimeException"/>  
30. <tx:method name="del*" propagation="REQUIRED"/>  
31. <tx:method name="*" propagation="REQUIRED" read-only="true"/>  
32. </tx:attributes>  
33. </tx:advice>  
34.       
35. <aop:config>  
36. <aop:pointcut expression="execution(* com.dao.*.*(..))" id="daoMethod"/>  
37. <aop:advisor advice-ref="txadvice" pointcut-ref="daoMethod"/>  
38. </aop:config>  
39. >  
40. <!-- 第二种配置事务的方式,代理 -->  
41.       
42. <bean id="transactionProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" abstract="true">  
43.        
44.         <!-- 使用cglib方式实现动态代理  
45. <property name="proxyTargetClass" value="true"></property>  
46. >  
47.            
48. <property name="transactionManager" ref="transactionManager"></property>  
49. <property name="transactionAttributes">  
50. <props>  
51. <prop key="add*">PROPAGATION_REQUIRED, +RuntimeException</prop>  
52. <prop key="modify*">PROPAGATION_REQUIRED, +com.exception.MyRuntimeException</prop>  
53. <prop key="del*">PROPAGATION_REQUIRED</prop>  
54. <prop key="*">PROPAGATION_REQUIRED, readOnly</prop>  
55. </props>  
56. </property>  
57. </bean>  
58.       
59. <bean id="userDao" parent="transactionProxy">  
60. <property name="target">  
61.            
62. <!-- 直接写bean来代替ref标签的链接方式 -->  
63.                
64. <bean class="com.dao.impl.UserDaoImpl">  
65. <property name="sessionFactory" ref="sessionFactory"></property>  
66. </bean>              
67. </property>  
68. </bean>  
69.        
70. </beans>



hibernate.cfg.xml文件的配置内容:



 

1. <?xml version="1.0" encoding="ISO-8859-1"?>  
2. <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">  
3.   
4. <hibernate-configuration>  
5. <session-factory>  
6. <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>  
7. <property name="hibernate.connection.url">jdbc:mysql://localhost/mytest</property>  
8. <property name="hibernate.connection.username">root</property>  
9. <property name="hibernate.connection.password">123456</property>  
10. <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>  
11. <property name="hibernate.show_sql">true</property>  
12. <property name="hibernate.hbm2ddl.auto">update</property>  
13. <mapping resource="com/entity/User.hbm.xml"/>  
14. </session-factory>  
15. </hibernate-configuration>



以上配置文件除web.xml文件外均存在于src目录下得config文件夹中。

最后是相关Java类的编写(UserDao):





1. package com.dao;  
2.   
3. import com.entity.User;  
4.   
5. public interface UserDao {  
6.       
7. public void addUser(User user) throws Exception;  
8.       
9. public void modifyUser(User user);  
10.       
11. public void delUser(String username);  
12. }



UserDaoImpl类实现UserDao接口:



 

1. package com.dao.impl;  
2.   
3. import org.hibernate.SessionFactory;  
4. import org.springframework.orm.hibernate3.HibernateTemplate;  
5.   
6. import com.dao.UserDao;  
7. import com.entity.User;  
8. import com.exception.MyRuntimeException;  
9.   
10. public class UserDaoImpl extends HibernateTemplate implements UserDao {  
11.       
12. private SessionFactory sessionFactory;  
13.       
14. @Override  
15. public void addUser(User user) throws Exception {  
16. this.save(user);  
17. //throw new Exception();  
18. throw new RuntimeException();  
19.     }  
20.   
21. @Override  
22. public void modifyUser(User user) {  
23. this.update(user);  
24. throw new MyRuntimeException();  
25.     }  
26.   
27. @Override  
28. public void delUser(String username) {  
29. this.delete(this.load(User.class, username));  
30.     }  
31.   
32. public void selectUser() {  
33.   
34.     }  
35. }


 

两个自定义的异常,MyException和MyRuntimeException:


 


1. package com.exception;  
2.   
3. import java.io.PrintStream;  
4. import java.io.PrintWriter;  
5.   
6. public class MyException extends Exception {  
7.   
8. @Override  
9. public void printStackTrace() {  
10. super.printStackTrace();  
11.     }  
12.   
13. @Override  
14. public void printStackTrace(PrintStream arg0) {  
15. super.printStackTrace(arg0);  
16.     }  
17.   
18. @Override  
19. public void printStackTrace(PrintWriter arg0) {  
20. super.printStackTrace(arg0);  
21.     }  
22.   
23. }


 


 


1. package com.exception;  
2.   
3. public class MyRuntimeException extends RuntimeException {  
4.       
5. }



UserManager类,UserManager通过调用UserDaoImpl类的addUser()方法对数据进行持久化:


 

1. package com.service;  
2.   
3. import javax.annotation.Resource;  
4.   
5. import com.dao.UserDao;  
6. import com.entity.User;  
7.   
8. public class UserManager {  
9.       
10. private UserDao userDao;  
11.   
12. public UserDao getUserDao() {  
13. return userDao;  
14.     }  
15.   
16. public void setUserDao(UserDao userDao) {  
17. this.userDao = userDao;  
18.     }  
19.   
20. public void addUser(User user) throws Exception {  
21.         userDao.addUser(user);  
22.     }  
23.   
24. public void modifyUser(User user) {  
25.         userDao.modifyUser(user);  
26.     }  
27.   
28. public void delUser(String username) {  
29.         userDao.delUser(username);  
30.     }  
31. }


 

UserManagerAction类,该类介于jsp页面与UserManager类之间,通过接收jsp页面传过来的数据作为调用UserManager类的addUser()方法的参数:



 

1. package com.action;  
2.   
3. import javax.annotation.Resource;  
4.   
5. import com.entity.User;  
6. import com.opensymphony.xwork2.ActionSupport;  
7. import com.service.UserManager;  
8.   
9. public class UserManagerAction extends ActionSupport {  
10.       
11. private User user;  
12.   
13. private UserManager userManager;  
14.   
15. public User getUser() {  
16. return user;  
17.     }  
18.   
19. public void setUser(User user) {  
20. this.user = user;  
21.     }  
22.       
23.       
24.   
25. public UserManager getUserManager() {  
26. return userManager;  
27.     }  
28.   
29. public void setUserManager(UserManager userManager) {  
30. this.userManager = userManager;  
31.     }  
32.   
33. public String addUser() throws Exception {  
34. "---------UserAction.addUser()-----------");  
35.         userManager.addUser(user);  
36. return "success";  
37.     }  
38.       
39. public String modifyUser() {  
40. "---------UserAction.modifyUser()-----------");  
41.         userManager.modifyUser(user);  
42. return "success";  
43.     }  
44.       
45. public String delUser() {  
46. "---------UserAction.delUser()-----------");  
47.         userManager.delUser(user.getUsername());  
48. return "success";  
49.     }  
50.   
51. @Override  
52. public String execute() throws Exception {  
53. return addUser();  
54.     }  
55. }



 

User实体类:



 

1. package com.entity;  
2.   
3. import javax.persistence.Column;  
4. import javax.persistence.Entity;  
5. import javax.persistence.Id;  
6. import javax.persistence.Table;  
7.   
8. /**
9.  * 
10.  * @author yang
11.  * @hibernate.class table="T_User"
12.  */  
13. public class User {  
14.   
15. /**
16.      * @hibernate.id
17.      *   generator-class="native"
18.      */  
19. private int id;  
20.       
21. /**
22.      * @hibernate.property
23.      */  
24. private String username;  
25.   
26. /**
27.      * @hibernate.property
28.      */  
29. private String password;  
30.   
31. /**
32.      * @hibernate.property
33.      */  
34. private int age;  
35.   
36. public int getId() {  
37. return id;  
38.     }  
39.   
40. public void setId(int id) {  
41. this.id = id;  
42.     }  
43.   
44. public String getUsername() {  
45. return username;  
46.     }  
47.   
48. public void setUsername(String username) {  
49. this.username = username;  
50.     }  
51.   
52. public String getPassword() {  
53. return password;  
54.     }  
55.   
56. public void setPassword(String password) {  
57. this.password = password;  
58.     }  
59.   
60. public int getAge() {  
61. return age;  
62.     }  
63.   
64. public void setAge(int age) {  
65. this.age = age;  
66.     }  
67. }


 

最后是jsp页面代码:



 

1. <%@ page language="java" contentType="text/html; charset=UTF-8"  
2. pageEncoding="UTF-8"%>  
3. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">  
4. <html>  
5. <head>  
6. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
7. <title>Insert title here</title>  
8. </head>  
9. <body>  
10. <form action="regist">  
11. <input name="user.username" type="text"><br>  
12. <input name="user.password" type="password"><br>  
13. <input name="user.age" type="text"><br>  
14. <input type="submit" value="注册">  
15. </form>  
16. </body>  
17. </html>



上面是添加整个用户的流程,简单来讲就是regist.jsp页面将页面数据提交到UserManagerAction,通过一系列的调用过程实现数据的持久化。在applicationContext-commons.xml文件中列举了两种配置事务的两种方式,这两种方式总的来讲本质上是一样的,只不过第二种是用代理方式。说到事务这里不得不提一句Spring的回滚机制。Spring对Exception和RuntimeException的处理方式是不一样的,如果是出现的是Exception(包含其子类)Spring会认为其是可修复的异常,这样的异常在默认情况下是不回滚的,而RuntimeException(包含其子类)则会被认为是不可恢复的异常,遇到这样的异常默认情况下是进行回滚的,所以如果我们根据自己的需要,想在抛出Exception的时候也想回滚,或在抛出RuntimeException的时候不想回滚的话就可以在applicationContext-commons.xml文件的事务配置部分配置roll-back-for(针对第一种事务配置方式),或以+,-方式(针对第二种事务配置方式)进行自定义配置即可。