hibernate4整合spring3事務問題

<?xml version="1.0" encoding="UTF-8"?>   
<beans xmlns="http://www.springframework.org/schema/beans"   
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
       xmlns:p="http://www.springframework.org/schema/p"    
       xmlns:aop="http://www.springframework.org/schema/aop"   
       xmlns:tx="http://www.springframework.org/schema/tx"    
       xsi:schemaLocation="     
          http://www.springframework.org/schema/beans      
          http://www.springframework.org/schema/beans/spring-beans-3.0.xsd   
          http://www.springframework.org/schema/aop      
          http://www.springframework.org/schema/aop/spring-aop-3.0.xsd     
          http://www.springframework.org/schema/tx      
          http://www.springframework.org/schema/tx/spring-tx-3.0.xsd   ">  
      
<!-- 配置數據源 Hibernate支持  -->  
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" >  
        <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>  
        <property name="username" value="scott" />  
        <property name="password" value="tiger" />  
        <property name="url" value="jdbc:oracle:thin:@localhost:1521:myorcl" />  
    </bean>  
    <!--     class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">-->  
    <bean id="sessionFactory"   
            class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" >  
        <property name="dataSource">  
            <ref bean="dataSource" />  
        </property>  
        <property name="hibernateProperties">  
            <props>  
                <prop key="hibernate.dialect">  
                    org.hibernate.dialect.Oracle9Dialect  
                </prop>  
                <prop key="hibernate.show_sql">true</prop>  
                <prop key="hibernate.temp.use_jdbc_metadata_defaults">false</prop>  
            </props>  
        </property>  
        <property name="mappingResources">  
            <list>  
                <value>com/neusoft/leehom/model/Emp.hbm.xml</value>  
                <value>com/neusoft/leehom/model/Dept.hbm.xml</value>  
            </list>  
        </property>  
    </bean>      
     <!-- 事務管理器 -->  
    <bean id="transactionManager"   
    class="org.springframework.orm.hibernate4.HibernateTransactionManager">  
        <property name="sessionFactory" ref="sessionFactory"></property>  
    </bean>  
    <!-- 配置那些類的方法進行事務管理,須要aopalliance-1.0.jar和aspectjweaver.jar,當前com.neusoft.leehom.service包中的子包,  
                       類中全部方法須要,還須要參考tx:advice的設置 -->  
    <!-- 須要引入tx的命名空間 -->  
    <!-- 這是事務通知操做,使用的事務管理器引用自 transactionManager -->  
    <tx:advice id="txAdvice" transaction-manager="transactionManager">  
        <tx:attributes>  
         <!-- 指定哪些方法須要加入事務,這裏懶惰一下所有加入,能夠使用通配符來只加入須要的方法 -->  
            <tx:method name="insert*" propagation="REQUIRED" />  
            <tx:method name="update*" propagation="REQUIRED" />  
            <tx:method name="delete*" propagation="REQUIRED" />  
            <tx:method name="get*" propagation="REQUIRED" read-only="true"/>  
            <tx:method name="query*" propagation="REQUIRED" read-only="true"/>  
            <tx:method name="*" propagation="REQUIRED" />  
        </tx:attributes>  
    </tx:advice>   
    <!-- 須要引入aop的命名空間 -->  
    <aop:config>  
        <!-- 切入點指明瞭在執行Service的全部方法時產生事務攔截操做 -->  
        <aop:pointcut id="daoMethods" expression="execution(* com.neusoft.leehom.service.impl.*.*(..))" />      
        <!-- 定義了將採用何種攔截操做,這裏引用到 txAdvice -->  
        <aop:advisor advice-ref="txAdvice" pointcut-ref="daoMethods" />  
    </aop:config>           
</beans>

配置事務時應該加載aopalliance-1.0.jar和aspectjweaver.jar這兩個包,這兩個包是必須的。覺得這樣就能夠對事務進行控制了,可是沒有想到在測試的時候發現dao層中的save、delete等方法都不能進行持久化。最終發現是取到的session不能爲sessionFactory.openSession(),而是應該爲sessionFactory.getCurrentSession().同時應該在配置爲文件中的propagation傳播方式最好爲required。這是由於當有一個方法list 傳播行爲爲Supports,當在另外一個方法getPage()(無事務)調用list方法時會拋出org.hibernate.HibernateException: No Session found for current thread 異常。java

根本緣由是getCurrentSession()在沒有session的狀況下不會自動建立一個,所以最好的解決方案是使用REQUIRED的傳播行爲。spring

如今知道事務的配置了,下面來看一下怎麼使用事務管理。sql

dao層部分代碼:express

package com.neusoft.leehom.dao;  
public class EmpDAO  {  
    private static final Logger log = LoggerFactory.getLogger(EmpDAO.class);  
    // property constants  
    public static final String ENAME = "ename";  
    public static final String JOB = "job";  
    public static final String MGR = "mgr";  
    public static final String SAL = "sal";  
    public static final String COMM = "comm";  
      
        private SessionFactory sessionFactory;  
      
    public Session getSession() {  
        return sessionFactory.getCurrentSession();  
    }  
  
    public SessionFactory getSessionFactory() {  
        return sessionFactory;  
    }  
  
    public void setSessionFactory(SessionFactory sessionFactory) {  
        this.sessionFactory = sessionFactory;  
    }  
  
    public void save(Emp transientInstance) {  
        log.debug("saving Emp instance");  
        try {   
            Session session = getSession();   
            session.save(transientInstance);          
            log.debug("save successful");  
        } catch (RuntimeException re) {  
            log.error("save failed", re);  
            throw re;  
        }  
    }  
  
    public void delete(Emp persistentInstance) {  
        log.debug("deleting Emp instance");  
        try {  
            Session session = getSession();   
            session.delete(persistentInstance);  
            log.debug("delete successful");  
        } catch (RuntimeException re) {  
            log.error("delete failed", re);  
            throw re;  
        }  
    }  
..........  
}

service層部分代碼:apache

package com.neusoft.leehom.service.impl;  
public class EmpManagerImpl implements IEmpManager {  
    private EmpDAO empDao;  
    /** 
     * 查詢全部的數據信息 
     */  
    public List queryAll() {  
        return empDao.findAll();  
    }  
    /** 
     * 插入數據 
     */  
    public void insertEmp(Emp emp){       
        empDao.save(emp);  
    }  
    /** 
     * 刪除數據 
     */  
    public void deleteEmp(short id) {  
        Emp emp = empDao.findById(id);  
        empDao.delete(emp);  
    }  
    public void setEmpDao(EmpDAO empDao) {  
        this.empDao = empDao;  
    }  
.......  
}
相關文章
相關標籤/搜索