zoukankan      html  css  js  c++  java
  • hibernate4整合spring3事务问题

    本文是作者在对hibernate4+spring3+struts2整合中遇到的一个问题。对s2sh进行了基本的整合搭建以后,就是对事务的控制管理,将hibernate的事务交由spring管理。根据网上资料,applicationContext.xml中基本的配置如下(注意先后顺序的问题):

    [html] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    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:p="http://www.springframework.org/schema/p"    
    5.        xmlns:aop="http://www.springframework.org/schema/aop"   
    6.        xmlns:tx="http://www.springframework.org/schema/tx"    
    7.        xsi:schemaLocation="     
    8.           http://www.springframework.org/schema/beans      
    9.           http://www.springframework.org/schema/beans/spring-beans-3.0.xsd   
    10.           http://www.springframework.org/schema/aop      
    11.           http://www.springframework.org/schema/aop/spring-aop-3.0.xsd     
    12.           http://www.springframework.org/schema/tx      
    13.           http://www.springframework.org/schema/tx/spring-tx-3.0.xsd   ">  
    14.       
    15. <!-- 配置数据源 Hibernate支持  -->  
    16.     <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" >  
    17.         <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>  
    18.         <property name="username" value="scott" />  
    19.         <property name="password" value="tiger" />  
    20.         <property name="url" value="jdbc:oracle:thin:@localhost:1521:myorcl" />  
    21.     </bean>  
    22.     <!--     class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">-->  
    23.     <bean id="sessionFactory"   
    24.             class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" >  
    25.         <property name="dataSource">  
    26.             <ref bean="dataSource" />  
    27.         </property>  
    28.         <property name="hibernateProperties">  
    29.             <props>  
    30.                 <prop key="hibernate.dialect">  
    31.                     org.hibernate.dialect.Oracle9Dialect  
    32.                 </prop>  
    33.                 <prop key="hibernate.show_sql">true</prop>  
    34.                 <prop key="hibernate.temp.use_jdbc_metadata_defaults">false</prop>  
    35.             </props>  
    36.         </property>  
    37.         <property name="mappingResources">  
    38.             <list>  
    39.                 <value>com/neusoft/leehom/model/Emp.hbm.xml</value>  
    40.                 <value>com/neusoft/leehom/model/Dept.hbm.xml</value>  
    41.             </list>  
    42.         </property>  
    43.     </bean>      
    44.      <!-- 事务管理器 -->  
    45.     <bean id="transactionManager"   
    46.     class="org.springframework.orm.hibernate4.HibernateTransactionManager">  
    47.         <property name="sessionFactory" ref="sessionFactory"></property>  
    48.     </bean>  
    49.     <!-- 配置那些类的方法进行事务管理,需要aopalliance-1.0.jar和aspectjweaver.jar,当前com.neusoft.leehom.service包中的子包,  
    50.                        类中所有方法需要,还需要参考tx:advice的设置 -->  
    51.     <!-- 需要引入tx的命名空间 -->  
    52.     <!-- 这是事务通知操作,使用的事务管理器引用自 transactionManager -->  
    53.     <tx:advice id="txAdvice" transaction-manager="transactionManager">  
    54.         <tx:attributes>  
    55.          <!-- 指定哪些方法需要加入事务,这里懒惰一下全部加入,可以使用通配符来只加入需要的方法 -->  
    56.             <tx:method name="insert*" propagation="REQUIRED" />  
    57.             <tx:method name="update*" propagation="REQUIRED" />  
    58.             <tx:method name="delete*" propagation="REQUIRED" />  
    59.             <tx:method name="get*" propagation="REQUIRED" read-only="true"/>  
    60.             <tx:method name="query*" propagation="REQUIRED" read-only="true"/>  
    61.             <tx:method name="*" propagation="REQUIRED" />  
    62.         </tx:attributes>  
    63.     </tx:advice>   
    64.     <!-- 需要引入aop的命名空间 -->  
    65.     <aop:config>  
    66.         <!-- 切入点指明了在执行Service的所有方法时产生事务拦截操作 -->  
    67.         <aop:pointcut id="daoMethods" expression="execution(* com.neusoft.leehom.service.impl.*.*(..))" />      
    68.         <!-- 定义了将采用何种拦截操作,这里引用到 txAdvice -->  
    69.         <aop:advisor advice-ref="txAdvice" pointcut-ref="daoMethods" />  
    70.     </aop:config>           
    71. </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 异常。

    根本原因是getCurrentSession()在没有session的情况下不会自动创建一个,因此最好的解决方案是使用REQUIRED的传播行为。

    现在知道事务的配置了,下面来看一下怎么使用事务管理。

    dao层部分代码:

    [java] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. package com.neusoft.leehom.dao;  
    2. public class EmpDAO  {  
    3.     private static final Logger log = LoggerFactory.getLogger(EmpDAO.class);  
    4.     // property constants  
    5.     public static final String ENAME = "ename";  
    6.     public static final String JOB = "job";  
    7.     public static final String MGR = "mgr";  
    8.     public static final String SAL = "sal";  
    9.     public static final String COMM = "comm";  
    10.       
    11.         private SessionFactory sessionFactory;  
    12.       
    13.     public Session getSession() {  
    14.         return sessionFactory.getCurrentSession();  
    15.     }  
    16.   
    17.     public SessionFactory getSessionFactory() {  
    18.         return sessionFactory;  
    19.     }  
    20.   
    21.     public void setSessionFactory(SessionFactory sessionFactory) {  
    22.         this.sessionFactory = sessionFactory;  
    23.     }  
    24.   
    25.     public void save(Emp transientInstance) {  
    26.         log.debug("saving Emp instance");  
    27.         try {   
    28.             Session session = getSession();   
    29.             session.save(transientInstance);          
    30.             log.debug("save successful");  
    31.         } catch (RuntimeException re) {  
    32.             log.error("save failed", re);  
    33.             throw re;  
    34.         }  
    35.     }  
    36.   
    37.     public void delete(Emp persistentInstance) {  
    38.         log.debug("deleting Emp instance");  
    39.         try {  
    40.             Session session = getSession();   
    41.             session.delete(persistentInstance);  
    42.             log.debug("delete successful");  
    43.         } catch (RuntimeException re) {  
    44.             log.error("delete failed", re);  
    45.             throw re;  
    46.         }  
    47.     }  
    48. ..........  
    49. }  

    service层部分代码:

    [java] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. package com.neusoft.leehom.service.impl;  
    2. public class EmpManagerImpl implements IEmpManager {  
    3.     private EmpDAO empDao;  
    4.     /** 
    5.      * 查询所有的数据信息 
    6.      */  
    7.     public List queryAll() {  
    8.         return empDao.findAll();  
    9.     }  
    10.     /** 
    11.      * 插入数据 
    12.      */  
    13.     public void insertEmp(Emp emp){       
    14.         empDao.save(emp);  
    15.     }  
    16.     /** 
    17.      * 删除数据 
    18.      */  
    19.     public void deleteEmp(short id) {  
    20.         Emp emp = empDao.findById(id);  
    21.         empDao.delete(emp);  
    22.     }  
    23.     public void setEmpDao(EmpDAO empDao) {  
    24.         this.empDao = empDao;  
    25.     }  
    26. .......  
    27. }  

    action层部分代码:

    [java] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. package com.neusoft.leehom.action;  
    2. public class EmpAction extends ActionSupport {  
    3.     private IEmpManager empManager;  
    4.     private List list;  
    5.     private String message;  
    6.     private Emp emp;  
    7.     /** 
    8.      * 查询所有记录 
    9.      * @return 
    10.      */  
    11.     public String showList(){  
    12.         list = empManager.queryAll();  
    13.         message = new String("shuju来说");  
    14.         //System.out.println(list);  
    15.         return new String("ok");  
    16.     }  
    17.     /** 
    18.      * 删除数据 
    19.      * @return 
    20.      */  
    21.     public String delete(){  
    22.         System.out.println(emp.getEmpno());  
    23.         if(emp.getEmpno()!=null && !"".equals(emp.getEmpno())){  
    24.             empManager.deleteEmp(emp.getEmpno());  
    25.         }  
    26.         return new String("delete_ok");  
    27.     }  
    28.     /** 
    29.      * 修改数据 
    30.      * @return 
    31.      */  
    32.     public String update(){  
    33.         System.out.println(emp.getEmpno());  
    34.         empManager.updateEmp(emp.getEmpno());  
    35.         return new String("update");  
    36.     }  
    37.     /** 
    38.      * 插入数据 
    39.      * @return 
    40.      */  
    41.     public String insert(){  
    42.         System.out.println(emp.getEname()+"--"+emp.getEmpno());  
    43.         empManager.insertEmp(emp);  
    44.         return new String("insert_ok");  
    45.     }  
    46. ........      
    47. }  

    applicationContext.xml配置文件后面增加如下代码:

    [html] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. <bean name="empDao" class="com.neusoft.leehom.dao.EmpDAO" >  
    2.         <property name="sessionFactory">  
    3.          <ref bean="sessionFactory" />  
    4.     </property>  
    5. </bean>  
    6. <bean name="empManager" class="com.neusoft.leehom.service.impl.EmpManagerImpl">  
    7.         <property name="empDao" ref="empDao"></property>  
    8. </bean>      
    9. <bean id="empAction" class="com.neusoft.leehom.action.EmpAction" >  
    10.         <property name="empManager" ref="empManager"></property>  
    11. </bean>  


    struts.xml的部分配置内容如下:

    [html] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. <package name="my" namespace="/" extends="struts-default">  
    2.         <action name="*_emp" class="empAction" method="{1}">  
    3.             <result name="ok">/show.jsp</result>  
    4.             <result name="insert_ok">/insert.jsp</result>  
    5.             <result name="delete_ok">/delete.jsp</result>  
    6.             <result name="update_ok">/update.jsp</result>  
    7.         </action>  
    8. </package>  

    注意:struts也是交与spring管理,如上的struts.xml中的class=“empAction”,会到spring的配置文件找id为empAction的bean,从而找到具体的实现类。

  • 相关阅读:
    软件测试工程师linux十大场景命令使用
    用yum安装软件显示错误:cannot find a valid baseurl for repo: base
    Redis安装、启动与多端口配置
    Linux vi编辑器
    cookie 和session、三种保持登陆会话的方式
    服务器内存溢出问题
    selenium多窗口切换
    Turtle库的学习积累
    高频ES6
    事件冒泡和捕获的执行顺序
  • 原文地址:https://www.cnblogs.com/LuckyBao/p/5979234.html
Copyright © 2011-2022 走看看