hibernate4整合spring3事务问题

来源:互联网 发布:js href带参数跳转 编辑:程序博客网 时间:2024/05/16 01:52
本文是作者在对hibernate4+spring3+struts2整合中遇到的一个问题。对s2sh进行了基本的整合搭建以后,就是对事务的控制管理,将hibernate的事务交由spring管理。根据网上资料,applicationContext.xml中基本的配置如下(注意先后顺序的问题):

<?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 异常。

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

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

dao层部分代码:

package com.neusoft.leehom.dao;public class EmpDAO  {private static final Logger log = LoggerFactory.getLogger(EmpDAO.class);// property constantspublic 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层部分代码:

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;}.......}
action层部分代码:

package com.neusoft.leehom.action;public class EmpAction extends ActionSupport {private IEmpManager empManager;private List list;private String message;private Emp emp;/** * 查询所有记录 * @return */public String showList(){list = empManager.queryAll();message = new String("shuju来说");//System.out.println(list);return new String("ok");}/** * 删除数据 * @return */public String delete(){System.out.println(emp.getEmpno());if(emp.getEmpno()!=null && !"".equals(emp.getEmpno())){empManager.deleteEmp(emp.getEmpno());}return new String("delete_ok");}/** * 修改数据 * @return */public String update(){System.out.println(emp.getEmpno());    empManager.updateEmp(emp.getEmpno());return new String("update");}/** * 插入数据 * @return */public String insert(){System.out.println(emp.getEname()+"--"+emp.getEmpno());empManager.insertEmp(emp);return new String("insert_ok");}........}
applicationContext.xml配置文件后面增加如下代码:

<bean name="empDao" class="com.neusoft.leehom.dao.EmpDAO" >     <property name="sessionFactory">     <ref bean="sessionFactory" /></property></bean><bean name="empManager" class="com.neusoft.leehom.service.impl.EmpManagerImpl">        <property name="empDao" ref="empDao"></property></bean>    <bean id="empAction" class="com.neusoft.leehom.action.EmpAction" >        <property name="empManager" ref="empManager"></property></bean>

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

<package name="my" namespace="/" extends="struts-default">    <action name="*_emp" class="empAction" method="{1}">    <result name="ok">/show.jsp</result>    <result name="insert_ok">/insert.jsp</result>    <result name="delete_ok">/delete.jsp</result>    <result name="update_ok">/update.jsp</result>    </action></package>
注意:struts也是交与spring管理,如上的struts.xml中的class=“empAction”,会到spring的配置文件找id为empAction的bean,从而找到具体的实现类。


原创粉丝点击