我有一个带有两个 Hibernate 数据源的 Spring Web 应用程序,它们由两个单独的事务管理器管理。数据源是完全独立的,模式方面的。此配置通过了所有单元测试和集成测试,但是当我在 Jetty 中部署它时,存储库操作失败,并出现以下异常:
org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named my_transactionManager1' is defined: No unique PlatformTransactionManager bean found for qualifier 'my_transactionManager1'
at org.springframework.beans.factory.annotation.BeanFactoryAnnotationUtils.qualifiedBeanOfType(BeanFactoryAnnotationUtils.java:84)
at org.springframework.beans.factory.annotation.BeanFactoryAnnotationUtils.qualifiedBeanOfType(BeanFactoryAnnotationUtils.java:55)
at org.springframework.transaction.interceptor.TransactionAspectSupport.determineTransactionManager(TransactionAspectSupport.java:246)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:100)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:625)
at my.controller.Class$$EnhancerByCGLIB$$3976e5ef.myMethodCall(<generated>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
持久性.xml
<persistence-unit name="pu1">
<properties>
<property name="hibernate.dialect" value="${hibernate.dialect}" />
<property name="hibernate.connection.url" value="${network.db.url}" />
<property name="hibernate.connection.driver_class" value="${hibernate.connection.driver_class}" />
<property name="hibernate.connection.username" value="{db.username}" />
<property name="hibernate.connection.password" value="{db.password}" />
<property name="hibernate.enable_lazy_load_no_trans" value="true"/>
<property name="hibernate.hbm2ddl.auto" value="${hibernate.hbm2ddl.auto}" />
<property name="hibernate.show_sql" value="false" />
</properties>
查看日志,两个数据源的行为似乎都很正常(直到发生此错误)。以下是应用程序上下文:
<?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: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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/jdbc
http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.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">
<tx:annotation-driven transaction-manager="my_transactionManager1" />
<context:component-scan base-package="com.my.package"/>
<jpa:repositories
base-package="com.my.package" entity-manager-factory-ref="my_entityManagerFactory" transaction-manager-ref="my_transactionManager1">
</jpa:repositories>
<bean id="my_dataSource1" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="${my.db1.url}"/>
<property name="username" value="${db1.username}"/>
<property name="password" value="${db1.password}"/>
</bean>
<bean id="my_entityManagerFactory1"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="pu1" />
<property name="dataSource" ref="my_dataSource1" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="databasePlatform" value="${hibernate.dialect}"/>
<property name="generateDdl" value="false" />
<property name="database" value="HSQL"/>
</bean>
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
</props>
</property>
</bean>
<bean id="my_transactionManager1" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="my_entityManagerFactory1" />
<property name="dataSource" ref="my_dataSource1" />
<qualifier value="my_transactionManager1"/>
<property name="persistenceUnitName" value="pu1"/>
</bean>
</beans>
我试图注入 TransactionManager 的服务类:
Service
@Transactional(value="my_transactionManager1")
@PersistenceContext(unitName = "pu1", name="my_entityManagerFactory1")
public class MyServiceClass{
@Autowired
private Field myField
@Resource(name="my_transactionManager1")
private JpaTransactionManager my_transactionManager1;
/**
* Public no-arg constructor for bean initialization
*/
public MyServiceClass() {}
/**
* Protected IOC constructor for testing
*
* @param resultsService
*/
protected MyServiceClass(Field myField) {
this.myField = myField;
}
我尝试了很多不同的方法来解决这个问题。对于这种情况,经常建议的一件事是单个 JTA XA TransactionManager,但我想避免这种情况,至少在第一次通过时。建议的另一件事是使用 AbstractDataRoutingSource,但我也不想这样做。我的方法似乎站得住脚(如果不是最优的话),因为测试正在通过并且应用程序部署没有错误。这是我的 web.xml(对不起,冗长的帖子):
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="site" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:my-first-context-file.xml,
classpath:a-few-other-config-files.xml,
</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
<servlet>
<servlet-name>MyServeletName</servlet-name>
<servlet-class>
com.sun.jersey.spi.spring.container.servlet.SpringServlet
</servlet-class>
<init-param>
<param-name>
com.sun.jersey.config.property.packages
</param-name>
<param-value>com.my.package</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
</load-on-startup>
</servlet>
<!--More servlets -->
<!-- Servlet mapping stuff -->
</web-app>
任何帮助都将不胜感激。