We are using jOOQ and Kafka in one project. When we enabled Kafka transactions by providing spring.kafka.producer.transaction-id-prefix configuration property, transaction managers started to clash in JooqAutoConfiguration with the following exception. I would expect jOOQ auto-configuration to pick the right TX manager.
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'transactionProvider' defined in class path resource [org/springframework/boot/autoconfigure/jooq/JooqAutoConfiguration.class]: Unsatisfied dependency expressed through method 'transactionProvider' parameter 0; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'org.springframework.transaction.PlatformTransactionManager' available: expected single matching bean but found 2: transactionManager,kafkaTransactionManager
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:800)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:541)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1352)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1195)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1391)
at org.springframework.beans.factory.support.DefaultListableBeanFactory$DependencyObjectProvider.getIfAvailable(DefaultListableBeanFactory.java:2032)
at org.springframework.beans.factory.support.DefaultListableBeanFactory$DependencyObjectProvider.ifAvailable(DefaultListableBeanFactory.java:2043)
at org.springframework.boot.autoconfigure.jooq.JooqAutoConfiguration$DslContextConfiguration.lambda$jooqProvidersDefaultConfigurationCustomizer$5(JooqAutoConfiguration.java:118)
at org.springframework.boot.autoconfigure.jooq.JooqAutoConfiguration$OrderedDefaultConfigurationCustomizer.customize(JooqAutoConfiguration.java:142)
at org.springframework.boot.autoconfigure.jooq.JooqAutoConfiguration$DslContextConfiguration.lambda$jooqConfiguration$1(JooqAutoConfiguration.java:103)
at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183)
Our workaround was to disable JooqAutoConfiguration and configure jOOQ manually.
If there is no easy fix, can you please at least make SpringTransactionProvider overridable (ConditionalOnMissingBean) so we can override just that and not the whole auto-config.
Spring Boot Version: 2.7.5
Comment From: wilkinsona
OSS support for Spring Boot 2.5.x ended in May 2022. Please try with Spring Boot 2.6.x or 2.7.x and let us know if the problem still occurs.
Comment From: lukas-krecan
Sorry, it was my fat fingers mistyping. It should have been 2.7.5. Fixed in the description
Comment From: wilkinsona
Perhaps we should make the auto-configured SpringTransactionProvider @ConditionalOnSingleCandidate(PlatformTransactionManager.class) so that it backs off when there's more than one. Flagging for team attention.
Comment From: philwebb
We're a little worried that @ConditionalOnSingleCandidate would make the error harder to find. We think the best option would be to add @ConditionalOnMissingBean(TransactionProvider.class) to at least allow a custom TransactionProvider to be plugged in.