JDBCテンプレートを使用したSpring Bootプロジェクトバージョン2.3.0.M3をR2DBCに移行しようとしています。このプロジェクトではLiquibaseも使用しているため、JDBCを完全に取り除くことはできません。プロジェクトにspring-boot-starter-data-r2dbcとspring-boot-starter-jdbcの両方の依存関係があり、いずれかのテストを実行しようとすると次の例外が発生します。
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のtransactionManagerは、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;
}
ご覧のとおり、@ ConditionalOnMissingBeanアノテーションには、両方のBeanのインスタンスが作成される原因となるさまざまなタイプが含まれています。ただし、SpringクラスTransactionAspectSupportでは、determineTransactionManagerメソッドに次のコード行があります。
defaultTransactionManager = this.beanFactory.getBean(TransactionManager.class);
トランザクションマネージャーの種類であるDataSourceTransactionManagerとR2dbcTransactionManagerの両方がTransactionManagerインターフェイスを実装しているため、上記の両方のトランザクションマネージャーBeanが一致し、エラーが発生します。
この問題を解決または回避できた方がいらっしゃいますか。
前もって感謝します!
M. Deinumsの回答(ありがとう!)からのインスピレーションを得て、次の手順をプロジェクトに適用し、以前に失敗したテストが正常に実行されるようになりました。
spring.r2dbcプロパティのユーザー名、パスワード、およびURLを定義しましたが、変更する必要はありませんでした。
更新:
さらに、テストでTestcontainerを使用したため、静的ポートを割り当てることができませんでした。Liquibaseでデータベースポートを構成できるようにするために、SpringLiquibaseタイプのBean名liquibaseをオーバーライドし、liquibase Bean作成メソッドでDataSource(Beanとして公開されていない)を作成し、それをliquibase Beanに設定しました。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加