Я пытаюсь перенести проект Spring Boot версии 2.3.0.M3, который использовал шаблон JDB C, в R2DB C. В проекте также используется Liquibase, поэтому я не могу полностью избавиться от JDB C. У меня в проекте есть зависимости spring-boot-starter-data-r2db c и spring-boot-starter-jdb c, с которыми я получаю следующее исключение при попытке запустить один из моих тестов:
org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'org.springframework.transaction.TransactionManager' available: expected single matching bean but found 2: transactionManager,connectionFactoryTransactionManager
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveNamedBean(DefaultListableBeanFactory.java:1180)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveBean(DefaultListableBeanFactory.java:416)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:349)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:342)
at org.springframework.transaction.interceptor.TransactionAspectSupport.determineTransactionManager(TransactionAspectSupport.java:480)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:335)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:99)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:747)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:95)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:747)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:689)
...
Диспетчер bean-компонента connectionFactoryTransaction определяется следующим образом в классе Spring R2dbcTransactionManagerAutoConfiguration:
@Bean
@ConditionalOnMissingBean(ReactiveTransactionManager.class)
public R2dbcTransactionManager connectionFactoryTransactionManager(ConnectionFactory connectionFactory) {
return new R2dbcTransactionManager(connectionFactory);
}
Транзитный компонент Bean-компонента определяется следующим образом в классе Spring DataSourceTransactionManagerAutoConfiguration:
@Bean
@ConditionalOnMissingBean(PlatformTransactionManager.class)
DataSourceTransactionManager transactionManager(DataSource dataSource,
ObjectProvider<TransactionManagerCustomizers> transactionManagerCustomizers) {
DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(dataSource);
transactionManagerCustomizers.ifAvailable((customizers) -> customizers.customize(transactionManager));
return transactionManager;
}
1009 * Как видно, аннотация @ConditionalOnMissingBean содержит разные типы, которые приведут к созданию экземпляра обоих компонентов. Однако в классе Spring TransactionAspectSupport есть следующая строка кода в методе defineTransactionManager:
defaultTransactionManager = this.beanFactory.getBean(TransactionManager.class);
Поскольку оба типа менеджера транзакций, DataSourceTransactionManager и R2dbcTransactionManager, реализуют интерфейс TransactionManager, оба компонента менеджера транзакций работают как приведенное выше совпадение и возникнет ошибка.
Сейчас я обращаюсь, чтобы узнать, есть ли кто-нибудь, кому удалось решить или обойти эту проблему? Заранее спасибо!