这几天配置spring data jpa时,使用声明式事务碰到了一个奇怪的问题,无论怎么配置xml或在方法上使用@Transactional(value = "tm1")都会报如下找不到事务管理器的错误:
Exception in thread "main" org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [org.springframework.transaction.PlatformTransactionManager] is defined: expected single matching bean but found 2: tm2,tm1
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:365)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:331)
at org.springframework.transaction.interceptor.TransactionAspectSupport.determineTransactionManager(TransactionAspectSupport.java:370)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:271)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodIntercceptor.invoke(CrudMethodMetadataPostProcessor.java:122)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
at com.sun.proxy.$Proxy20.save(Unknown Source)
at org.fxbird.springjpa.service.DepartmentServiceImpl.addDeptAndEmp(DepartmentServiceImpl.java:47)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
at com.sun.proxy.$Proxy24.addDeptAndEmp(Unknown Source)
at org.fxbird.springjpa.App.main(App.java:15)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:365)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:331)
at org.springframework.transaction.interceptor.TransactionAspectSupport.determineTransactionManager(TransactionAspectSupport.java:370)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:271)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodIntercceptor.invoke(CrudMethodMetadataPostProcessor.java:122)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
at com.sun.proxy.$Proxy20.save(Unknown Source)
at org.fxbird.springjpa.service.DepartmentServiceImpl.addDeptAndEmp(DepartmentServiceImpl.java:47)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
at com.sun.proxy.$Proxy24.addDeptAndEmp(Unknown Source)
at org.fxbird.springjpa.App.main(App.java:15)
我的配置:
<?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:context="http://www.springframework.org/schema/context"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/jdbc
http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<aop:config>
<aop:pointcut id="serviceOperation" expression="execution(* org.fxbird.springjpa.service.*ServiceImpl.*(..))"/>
<aop:advisor pointcut-ref="serviceOperation" advice-ref="txAdvice"/>
</aop:config>
<tx:advice id="txAdvice" transaction-manager="tm1">
<tx:attributes>
<tx:method name="find*" read-only="true"/>
<tx:method name="count*" propagation="NEVER"/>
<tx:method name="*" />
</tx:attributes>
</tx:advice>
<bean abstract="true" id="baseDS" class="org.apache.commons.dbcp.BasicDataSource" lazy-init="true">
<property name="initialSize" value="3"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean>
<bean id="dataSource1" parent="baseDS">
<property name="url">
<value>jdbc:mysql://localhost/company?useUnicode=true&characterEncoding=utf-8</value>
</property>
</bean>
<bean id="dataSource2" parent="baseDS">
<property name="url">
<value>jdbc:mysql://localhost/employee?useUnicode=true&characterEncoding=utf-8</value>
</property>
</bean>
<bean abstract="true" id="baseEmf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="packagesToScan" value="org.fxbird.springjpa.model"/>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter"/>
</property>
<property name="jpaProperties">
<props>
<prop key="databasePlatform">org.eclipse.persistence.platform.database.MySQLPlatform</prop>
<prop key="eclipselink.jdbc.cache-statements">true</prop>
<prop key="eclipselink.weaving">false</prop>
<prop key="eclipselink.logging.level">FINEST</prop>
<prop key="eclipselink.allow-zero-id">true</prop>
<!--<prop key="eclipselink.target-server">com.atomikos.eclipselink.platform.AtomikosTransactionController</prop>-->
<!--<prop key="eclipselink.external-transaction-controller">true</prop>-->
</props>
</property>
</bean>
<bean id="emfCompany" parent="baseEmf">
<property name="dataSource" ref="dataSource1"/>
</bean>
<bean id="emfEmp" parent="baseEmf">
<property name="dataSource" ref="dataSource2"/>
</bean>
<bean id="tm1" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="emfCompany"/>
</bean>
<bean id="tm2" name="tm2" class="org.springframework.orm.jpa.JpaTransactionManager">
<qualifier value="tm2"/>
<property name="entityManagerFactory" ref="emfEmp"/>
</bean>
<context:component-scan base-package="org.fxbird.springjpa.service" />
<jpa:repositories base-package="org.fxbird.springjpa.repo.company" entity-manager-factory-ref="emfCompany" transaction-manager-ref="tm1"/>
<jpa:repositories base-package="org.fxbird.springjpa.repo.emp" entity-manager-factory-ref="emfEmp" transaction-manager-ref="tm2"/>
<tx:annotation-driven />
</beans>
后来我找来了书上的例子,却一切正常,仔细对比了代码的不同好几遍,没发现任何异常,头发却快掉了好几十根了
。第二天又试了一下,忽然怀疑是不是有可能jar包版本不同导致的,书上的例子用的是spring 4.0.2,而我用的是4.1.4,换成书上的版本一运行果然错误没了,shit,困扰我好几天了,又换成最新的4.1.6,也没有问题,看来就是版本问题了。
本文解决在配置Spring Data JPA时遇到的事务管理器版本不一致导致的NoUniqueBeanDefinitionException错误。通过比较实际配置与书中示例,最终确定版本不匹配是问题根源。
1万+

被折叠的 条评论
为什么被折叠?



