Java 具有 Spring 和 Hibernate 的应用程序从 3.2.1 升级到 4.3.2 以及从 4.2.0 升级到 5.2.1 抛出错误

Java application with Spring and Hibernate upgraded from 3.2.1 to 4.3.2 and 4.2.0 to 5.2.1 throwing error

应用程序抛出以下错误:

org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [org.springframework.transaction.PlatformTransactionManager] is defined: expected single matching bean but found 3

您好,我们有一个 web 应用程序,我们升级到上述配置,运行在 java 8,tomcat 8。在第一次与数据库交互(写入事务)时,应用程序抛出上述错误。

我们使用了 Spring 的 Hibernate 事务管理器 实现。我们定义了 spring aop 以包含 bo 方法 以及必要操作的事务和事务建议(回滚基本上) 在某些例外情况下。

注: JDK和tomcat也升级了,都是从6升级到8

在 Spring、Hibernate、tomcat 和 java 升级之前,我们在应用程序中有相同的配置(如下所述),它们曾经并且仍然正常工作,甚至一次都没有我们遇到了这个错误。

每个数据源、会话工厂和事务管理器定义如下 数据源是这样的

session factory configuration
<bean id="sessionFactory1" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource1"/>
    <property name="mappingResources">
       <list>
          <!-- List of hbm mappings -->
       </list>
    </property>
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">${hibernate.dialect}</prop>
            <prop key="hibernate.show_sql">true</prop>
            <prop key="hibernate.generate_statistics">true</prop>
            <prop key="hibernate.format_sql">false</prop>
            <prop key="hibernate.use_sql_comments">false</prop>
            <prop key="hibernate.connection.release_mode">after_transaction</prop>
            <prop key="hibernate.c3p0.timeout">1</prop>
        </props>
    </property>
</bean> 

Transaction manager, transaction advice and aop config
<bean id="transactionManager1" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory1"/>
</bean>
<tx:advice id="defaultTxAdvice1" transaction-manager="transactionManager1">
   <tx:attributes>
      <tx:method name="get*" read-only="true"/>
      <tx:method name="*" rollback-for="com.xyz.platformcore.common.exception.VyasaException"/>
   </tx:attributes>
</tx:advice>

<aop:config>
  <aop:pointcut id="serviceOperation1" expression="execution(* com..*BO.*(..)) || execution(* com..*Bo.*(..)) || execution(* com..*bo.*(..)) || execution(* com.xyz.platformcore..*BO.*(..)) || execution(* com.xyz.framework..*bo.*(..)) || execution(* com.xyz.framework..*Bo.*(..)) || execution(* com.xyz.platformcore..*Bo.*(..)) ||  @annotation(com.xyz.platformcore.common.hibernate.VyasaTransactionAwareHibernateOperation) || within(@com.xyz.platformcore.common.hibernate.VyasaTransactionAwareHibernateOperation *)" />
  <aop:advisor advice-ref="defaultTxAdvice1" pointcut-ref="serviceOperation1"/>
</aop:config>

My dao method

public void invalidateSomeThing() {
    Query query = getSession1().createQuery("update SomeThing set isActive =:isActive");
    query.setParameter("isActive", false);
    query.executeUpdate();
}
getSession1() gives the Session object from SessionFcatory1 which connects to DataSource1

非常感谢任何帮助

如 Spring 文档中所述:

NoUniqueBeanDefinitionException

Exception thrown when a BeanFactory is asked for a bean instance for which multiple matching candidates have been found when only one matching bean was expected.

所以基本上,您有三个 Spring "beans" of org.springframework.transaction.PlatformTransactionManager 具有相同的标识符 and/or 名称。最终,您可以拥有任意数量,但是 Spring 容器必须有办法 "identify" 它们...通常是按类型,然后是名称。

尝试在 debug 模式下在启动时记录输出;它会一步一步地告诉你你正在加载的豆子是什么以及类似的东西。无论如何,您应该在配置中的某处有三个定义 org.springframework.transaction.PlatformTransactionManager

请检查一下... "Transaction manager cache fails to repopulate when multiple transaction managers defined"

https://jira.spring.io/browse/SPR-14609

这是 Spring FW 4.3.2 版本中的错误。已在 4.3.3 中修复。

此致, --亚什