spring配置hibernate事务aop不生效的问题

来源:互联网 发布:淘宝如何提高售后评分 编辑:程序博客网 时间:2024/06/05 08:16

最近学习spring框架,在spring+hibernate整合中,配置事务遇到了麻烦,头疼了两天,最终豁然开朗。

后来才发现:是因为数据库操作对应的类没有配置对应的<bean id='' class=‘’></bean>导致。

事务配置分声明式和注解式,我用的是声明式(xml),两者核心配置原理相同。

spring整合hinernate方式:

1、定义DAO,继承HibernateTemplate,

2、配置数据库资源datasource(可用c3p0也可用hibernate原生连接池)

3、将datasource配置到sessionFactory

4、将sessionFactory注入到DAO(sessionFactory 为srping HibernateTemplate 类的私有属性,会自动set)

这样就配置好了,测试了一下,顺利!

配置如下:

<!--  配置dao,注入sessionFactory -->
    <bean name="dao" class="com.how2java.dao.CategoryDAO">
        <property name="sessionFactory" ref="sf" />
    </bean>

<!--  配置sessionFactory ,注入datasource-->

<bean id="sf"

class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="ds" />
<property name="mappingResources">
<list>
<value>com/how2java/pojo/Category.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<value>
hibernate.dialect=org.hibernate.dialect.MySQLDialect
hibernate.show_sql=true
hbm2ddl.auto=update
hibernate.format_sql=true
    </value>
</property>
</bean> 

<!--配置datasource,数据库连接 -->

<bean name="ds"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/how2java?characterEncoding=UTF-8" />
<property name="username" value="root" />
<property name="password" value="root" />
</bean>

----------------------------

但是,当配置事务的时候,遇到大乌龙,分析了很多遍,事务配置、代码逻辑,都没问题,但是批处理两条,其中一条失败,事务依旧不能回滚!!!

极大地打击了自信心,因为确实没问题啊?==!

配置如下:

<!-- 配置事务管理器(声明式的事务),sessionFactory交由hiberdate便于事务自动代理 -->  
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">  
   <property name="sessionFactory" ref="sf"></property>  
</bean>

<!-- 配置事务传播性  get*等为对应的方法名,正则匹配成功则aop切入事务-->
<bean id="transactionInterceptor"
class="org.springframework.transaction.interceptor.TransactionInterceptor">
<property name="transactionManager" ref="transactionManager" />
<property name="transactionAttributes">
<props>
<prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="load*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="query*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="disPlay*">PROPAGATION_REQUIRES_NEW</prop>
<prop key="insert*">PROPAGATION_REQUIRED</prop>
<prop key="del*">PROPAGATION_REQUIRED</prop>
<prop key="remove*">PROPAGATION_REQUIRED</prop>
<prop key="save*">PROPAGATION_REQUIRED</prop>
<prop key="update*">PROPAGATION_REQUIRED</prop>
<prop key="edit*">PROPAGATION_REQUIRED</prop>
<prop key="close*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>

<!--配置事务的入口execution(* com.how2java.test.*.*(..))  为切入点,表示包com.how2java.test下所有类的所有方法-->
    <aop:config>
    <aop:pointcut id="allServiceMethod" expression="execution(* com.how2java.test.*.*(..))"/>
    <aop:advisor pointcut-ref="allServiceMethod" advice-ref="transactionInterceptor"/>
    </aop:config>

后来才发现:是因为数据库操作对应的类没有配置对应的<bean id='' class=‘’></bean>导致!

 com.how2java.test.TestSpring并未配置对应的bean。直接new 然后调用 saveData方法,事务不生效。

加上<bean id="test" class="com.how2java.test.TestSpring"></bean>使用spring容器获取对象调用方法,事务生效。


原因是因为,该bean不交给spring容器进行管理,spring进行aop切面编制的时候,他无法识别,应为控制权没有给容器,所以失效。一个教训,AOP切面编程要注意啊,同时也要讲究分析问题的方法!


代码:

package com.how2java.test;
 
import java.util.List;


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


import com.how2java.dao.CategoryDAO;
import com.how2java.pojo.Category;
 
 
public class TestSpring {
public static ApplicationContext context;

static{
context = new ClassPathXmlApplicationContext(
                new String[] { "applicationContext.xml" });
System.out.println("成功初始化");
}
public void saveData(){
       CategoryDAO dao = (CategoryDAO) context.getBean("dao");
       Category c = new Category();
       c.setName("category yyy");
       
       //增加
       dao.save(c);
       
       //获取
       Category c2 = (Category) dao.get(Category.class, new Integer(1));
       
       //修改
       c2.setName("category zzzsssssssssssssssssssssssssssssssssssssssssss");
       dao.save(c2);
}
public static  void init(){
System.out.println("....");
}
    public static void main(String[] args) {

//之前该方法是直接new,没用spring容器去管理
    TestSpring ts = (TestSpring) context.getBean("test");
    ts.saveData();
    }
}


阅读全文
1 0
原创粉丝点击