spring error No qualifying bean of type JdbcTemplate

Multi tool use
spring error No qualifying bean of type JdbcTemplate
I have a spring boot application where I am creating Datasource
and JdbcTemplate
manually in my config because I need to decrypt datasource password.
Datasource
JdbcTemplate
I am using tomcat DataSource
(org.apache.tomcat.jdbc.pool.DataSource
) as recommended in spring boot docs since I am configuring connection properties.
DataSource
org.apache.tomcat.jdbc.pool.DataSource
I am excluding autoconfiguration for datasource (see Application.java
) since I am creating one manually.
Application.java
Application.java
// exclude datasourceAutoConfiguration since we are creating manaully creating datasource bean in AppConfig
@SpringBootApplication
@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
public class Application {
public static void main(String args) {
SpringApplication.run(Application.class, args);
}
}
Here is my application.properties
file
application.properties
jdbc.hostdb.url=jdbc:jtds:sqlserver://hello-world:1122/foobar
host.jdbc.hostdb.username=foo
host.jdbc.hostdb.password=encryptedPassword
host.jdbc.hostdb.driver=net.sourceforge.jtds.jdbc.Driver
secret=afasdfansdfsdfsd
AppConfig.java
import org.apache.tomcat.jdbc.pool.DataSource;
@ComponentScan("com.company.foo")
public class AppConfig {
@Value("${jdbc.hostdb.driver}")
private String driver;
@Value("${jdbc.hostdb.url}")
private String url;
@Value("${jdbc.hostdb.username}")
private String user;
@Value("${jdbc.hostdb.password}")
private String pass;
@Value("${secret}")
private String secret;
@Bean
public DataSource datasource_mydb(Encryption encryption) {
DataSource ds = new DataSource();
ds.setDriverClassName(hostdb_driver);
ds.setUrl(hostdb_url);
ds.setUsername(hostdb_user);
ds.setPassword(encryption.decrypt(hostdb_pass));
return ds;
}
@Bean
Encryption encryption() {
return new Encryption(secret);
}
@Bean
public JdbcTemplate jdbcTemplate(DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
}
MyRepository.java
@Repository
public class MyRepository {
JdbcTemplate jdbcTemplate;
@Autowired
public MyRepository(JdbcTemplate jdbcTemplate){
this.jdbcTemplate=jdbcTemplate;
}
}
when I start spring container, I get the following error
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'MyRepository' defined in file [/Users//Documents/codebase/my-service/build/classes/main/com/company/foo/MyRepository.class]: Unsatisfied dependency expressed through constructor argument with index 0 of type [org.springframework.jdbc.core.JdbcTemplate]: No qualifying bean of type [org.springframework.jdbc.core.JdbcTemplate] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.jdbc.core.JdbcTemplate] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:749) ~[spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:185) ~[spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1143) ~[spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1046) ~[spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:510) ~[spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482) ~[spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:772) ~[spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:839) ~[spring-context-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:538) ~[spring-context-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118) ~[spring-boot-1.3.6.RELEASE.jar:1.3.6.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:760) [spring-boot-1.3.6.RELEASE.jar:1.3.6.RELEASE]
at org.springframework.boot.SpringApplication.createAndRefreshContext(SpringApplication.java:360) [spring-boot-1.3.6.RELEASE.jar:1.3.6.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:306) [spring-boot-1.3.6.RELEASE.jar:1.3.6.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1185) [spring-boot-1.3.6.RELEASE.jar:1.3.6.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1174) [spring-boot-1.3.6.RELEASE.jar:1.3.6.RELEASE]
at com.concur.cognos.authentication.Application.main(Application.java:14) [main/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_102]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_102]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_102]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_102]
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144) [idea_rt.jar:na]
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.jdbc.core.JdbcTemplate] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1373) ~[spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1119) ~[spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1014) ~[spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:813) ~[spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:741) ~[spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
... 24 common frames omitted
2016-07-26 1
AppConfig
@Configuration
@SotiriosDelimanolis: yes, that fixed it. I dont know how I missed it. Thanks for catching it
– brain storm
Jul 27 '16 at 4:24
@SotiriosDelimanolis: i do need
@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
in order to avoid autoconfiguration or does spring sees my datasource bean and not autoconfigure it?– brain storm
Jul 27 '16 at 5:29
@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
@SotiriosDelimanolis: you may have an answer to this one, stackoverflow.com/questions/38511755/…
– brain storm
Jul 27 '16 at 5:30
You don't need to exclude the
DataSourceAutoConfiguration
as that is smart enough to see that you already added the DataSource
. You also don't need to create a JdbcTemplate
as that will be automatically created for you. So you only would need to create the DataSource
.– M. Deinum
Jul 27 '16 at 6:13
DataSourceAutoConfiguration
DataSource
JdbcTemplate
DataSource
1 Answer
1
The problem is with the arguments of your bean definitions. Where would their values come from? For example -
@Bean
public JdbcTemplate jdbcTemplate(DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
Here you haven't specified where would value of dataSource
argument come from. Same case of datasource_mydb
bean. Use @Autowire
on bean definitions acception other beans as input arguments.
dataSource
datasource_mydb
@Autowire
@Bean
@Autowired
public DataSource datasource_mydb(Encryption encryption) {
DataSource ds = new DataSource();
ds.setDriverClassName(hostdb_driver);
ds.setUrl(hostdb_url);
ds.setUsername(hostdb_user);
ds.setPassword(encryption.decrypt(hostdb_pass));
return ds;
}
@Bean
Encryption encryption() {
return new Encryption(secret);
}
@Bean
@Autowired
@Qualifier("datasource_mydb")
public JdbcTemplate jdbcTemplate(DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
I dont think it is necessary. @SotiriosDelimanolis what do you think?
– brain storm
Jul 27 '16 at 5:02
No, this isn't necessary at all. @brainstorm Spring will resolve arguments for
@Bean
methods by checking the context for corresponding beans. You've defined a DataSource
bean named datasource_mydb
and so it's available for the JdbcTemplate
bean method.– Sotirios Delimanolis
Jul 27 '16 at 5:19
@Bean
DataSource
datasource_mydb
JdbcTemplate
@SotiriosDelimanolis and doc link for validating this? If this is the case then the reason for OP's error is bean's name "datasource_mydb" which does not map by name "dataSource".
– Harshil Sharma
Jul 27 '16 at 6:02
Here's the official doc on this process. Injection doesn't happen by name here. It happens by type.
– Sotirios Delimanolis
Jul 27 '16 at 6:07
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
There's no bean defined for
AppConfig
. Maybe you meant to annotate it with@Configuration
.– Sotirios Delimanolis
Jul 27 '16 at 1:38