After upgrading out application from Spring Boot 2.2.8 to 2.3.0 (2.3.1 also fails) we are now getting the following error when running our tests:

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1714)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1270)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1224)
    at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:884)
    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:788)
    ... 108 more

Here's a simplistic reproduction example of it failing on 2.3.1 once I add in the r2dbc dependency: https://github.com/busches/spring-boot-issue

Comment From: wilkinsona

NamedParameterJdbcTemplate is for use with JDBC rather than R2DBC. You may not have spring-jdbc on the classpath which would stop it from being auto-configured.

If you would like us to spend some more time investigating, please spend some time providing a complete yet minimal sample that reproduces the problem. You can share it with us pushing it to a separate repository on GitHub or by zipping it up and attaching it to this issue.

Comment From: busches

NamedParameterJdbcTemplate is for use with JDBC rather than R2DBC. You may not have spring-jdbc on the classpath which would stop it from being auto-configured.

If you would like us to spend some more time investigating, please spend some time providing a complete yet minimal sample that reproduces the problem. You can share it with us pushing it to a separate repository on GitHub or by zipping it up and attaching it to this issue.

I can work on that, but it seems odd that if I change only to spring boot 2.3 it fails to find the bean. We use both R2DBC and JDBC, I only pointed out R2DBC as maybe it was causing a conflict.

Comment From: wilkinsona

There’s no R2DBC support in Spring Boot 2.2 so switching to 2.3 is more than just a version change. IIRC, the experimental R2DB2 support depended on spring-jdbc whereas the support that was added in Spring Boot 2.3 does not. You could check your dependencies and/or run with --debug to verify this for yourself.

Comment From: busches

There’s no R2DBC support in Spring Boot 2.2 so switching to 2.3 is more than just a version change. IIRC, the experimental R2DB2 support depended on spring-jdbc whereas the support that was added in Spring Boot 2.3 does not. You could check your dependencies and/or run with --debug to verify this for yourself.

Yea, that's not the issue at all, I believe it has to do with @TestComponent and bringing in the dependency. Here's a repro case: https://github.com/busches/spring-boot-issue

I have this test that passes with bringing it in via @Autowired: https://github.com/busches/spring-boot-issue/blob/master/src/test/kotlin/com/example/demo/PassingApplicationTests.kt And this test fails when it's brought in via a @TestComponent: https://github.com/busches/spring-boot-issue/blob/master/src/test/kotlin/com/example/demo/FailingApplicationTests.kt Downgrading to 2.2.8 and both pass.

Comment From: wilkinsona

Thanks for the sample, but it seems to fail with both 2.3.1 and 2.2.8. That's what I would expect as FailingApplicationTests is using classes = [MyComponent::class]. With class configuration, @SpringBootTest does not search for the main application class. As a result, DemoApplication and its @SpringBootApplication annotation aren't found so auto-configuration isn't enabled.

If you can provide a sample that passes with 2.2.x and fails with 2.3.x we can take another look. At the moment it looks to be user error as auto-configuration isn't enabled in FailingApplicationTests but you're trying to consume an auto-configured bean.

Comment From: busches

Thanks for the sample, but it seems to fail with both 2.3.1 and 2.2.8. That's what I would expect as FailingApplicationTests is using classes = [MyComponent::class]. With class configuration, @SpringBootTest does not search for the main application class. As a result, DemoApplication and its @SpringBootApplication annotation aren't found so auto-configuration isn't enabled.

If you can provide a sample that passes with 2.2.x and fails with 2.3.x we can take another look. At the moment it looks to be user error as auto-configuration isn't enabled in FailingApplicationTests but you're trying to consume an auto-configured bean.

Hmm, swore I had it failing in 2.2.8 as well, I must have made a mistake. I'll see if I can get it to fail with this simplistic example or if I need to make it more complicated to resemble our real example.

Comment From: busches

Once I changed my annotation to @SpringBootTest(classes = [DemoApplication::class, MyComponent::class]) it started working as expected in both 2.2.8 and 2.3.1.

I got it to fail in 2.3.1 as soon as I added the R2D2 dependency, in both examples. implementation("org.springframework.boot.:spring-boot-starter-data-r2dbc")

That dependency doesn't exist exactly in for 2.2.8, so it's hard to show an example that fails in both. I updated the example repository with the failure. If you want me to get an example that works on 2.2.8 and fails on 2.3.1, I'll need to spend a bit more time moving everything to the older version of r2dbc that's experimental for 2.2.8.

Thanks for the help so far.

Comment From: busches

I split the example repo into one that starts with 2.2.8 with R2DBC (still experimental) and swapping it to 2.3.1 will give the error: https://github.com/busches/spring-boot-issue/blob/master/spring-boot-2.2/build.gradle.kts I also have a fresh repo that started with 2.3.1 and I mentioned above, as soon as you add in the r2dbc starter it fails for the same reason. Hopefully this helps with the debugging or telling us what we're doing wrong. Thanks again.

Comment From: wilkinsona

Thanks for the sample. I can see what it happening now.

As noted in the documentation, the auto-configuration of a DataSource (and therefore any DataSource-related beans) backs off in the presence of an R2DBC ConnectionFactory bean. We do this because we believe that mixing JDBC and R2DBC in a reactive application should be discouraged by default as the danger of accidentally blocking an event loop thread by using JDBC on it is too great.

If you want to override this opinion and continue to make use of a DataSource in an application that is using R2DBC, you can do so by importing DataSourceAutoConfiguration:

@SpringBootApplication
@Import(DataSourceAutoConfiguration::class)
class DemoApplication

fun main(args: Array<String>) {
    runApplication<DemoApplication>(*args)
}

We can use this issue to update the documentation to describe how to opt back in, while also warning about the risks of using JDBC in a reactive application.

Comment From: busches

Thanks, that worked! I would have expected this to normally be documented in the release notes, but I'm guessing since r2dbc was experimental before 2.3 it didn't make the cut.

And for the record, I agree with why you disabled the JDBC stuff and we only use it in our integration tests similar to my example. :)

Thanks again for all your help.