Hibernate 宣告式交易管理


Spring對Hibernate提供宣告式的交易管理,這與 JDBC 宣告式交易管理 類似,先來介紹一下比較簡單的方式,直接從HibernateTemplateDemo專案來進行改寫,事實上您不需要修改UserDAO類別,而只要在定義檔上設定即可:
  • UserDAO.java
<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE beans PUBLIC "-//SPRING/DTD BEAN/EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="dataSource"
class="org.springframework.jdbc.
→ datasource.DriverManagerDataSource">
<property name="driverClassName">
<value>com.mysql.jdbc.Driver</value>
</property>
<property name="url">
<value>jdbc:mysql://localhost:3306/demo</value>
</property>
<property name="username">
<value>caterpillar</value>
</property>
<property name="password">
<value>123456</value>
</property>
</bean>

<bean id="sessionFactory"
class="org.springframework.orm.
→ hibernate3.LocalSessionFactoryBean"
destroy-method="destroy">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
<property name="mappingResources">
<list>
<value>onlyfun/caterpillar/User.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
org.hibernate.dialect.MySQLDialect
</prop>
</props>
</property>
</bean>

<bean id="userDAO" class="onlyfun.caterpillar.UserDAO">
<property name="sessionFactory">
<ref bean="sessionFactory"/>
</property>
</bean>

<bean id="transactionManager"
class="org.springframework.orm.
→ hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref bean="sessionFactory"/>
</property>
</bean>

<bean id="userDAOProxy"
class="org.springframework.transaction.
→ interceptor.TransactionProxyFactoryBean">
<property name="transactionManager">
<ref bean="transactionManager"/>
</property>
<property name="proxyInterfaces">
<list>
<value>onlyfun.caterpillar.IUserDAO</value>
</list>
</property>
<property name="target">
<ref bean="userDAO"/>
</property>
<property name="transactionAttributes">
<props>
<prop key="insert">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
</beans>

主要的差別在於設定檔中建立了transactionManager與userDAOProxy,由於Spring所提供的一致性的設定模型,所以設定的方式與 JDBC 宣告式交易管理  的設定方式是類似的。

來寫個程式測試一下,這次取回DAO代理物件來進行操作,如下所示:
  • SpringHibernateDemo.java
package onlyfun.caterpillar;

import org.springframework.context.ApplicationContext;
import org.springframework.context.
support.FileSystemXmlApplicationContext;

public class SpringHibernateDemo {
public static void main(String[] args) {
ApplicationContext context =
new FileSystemXmlApplicationContext(
"beans-config.xml");

// 建立DAO物件
IUserDAO userDAO =
(IUserDAO) context.getBean("userDAOProxy");

User user = new User();
user.setName("cater");
user.setAge(new Integer(30));

userDAO.insert(user);

user = userDAO.find(new Integer(1));

System.out.println("name: " + user.getName());
}
}

如果在執行insert()方法時發生了例外,則資料不會被新增至表格中,您可以自行在UserDAO類別中嘗試丟出個例外以測試交易的功能是否正確執行。

同樣的,在Spring中對Hibernate進行宣告式交易管理時,使用到Spring AOP的功能,所以您必須在Classpath的路徑設定中加入spring-aop.jar檔案才可以執行專案中的程式。