No bean named 'transactionManager' available - spring

When I tried to create relationship using spring code,
I am getting Transaction manager error. I am using Mysql and Neo4j database in my project. I tries different solution but not able to resolve.
org.springframework.beans.factory.NoSuchBeanDefinitionException: No
bean named 'transactionManager' available: No matching
PlatformTransactionManager bean found for qualifier
'transactionManager' - neither qualifier match nor bean name match!
Pom.xml file as below
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.10.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>1.5.10.RELEASE</version>
</dependency>
<!-- For Neo4J Graph Database -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-neo4j</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.9-rc</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
<version>1.5.10.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
</dependencies>
<properties>
<java.version>1.8</java.version>
<thymeleaf.version>3.0.2.RELEASE</thymeleaf.version>
<thymeleaf-layout-dialect.version>2.1.1</thymeleaf-layout-dialect.version>
</properties>
</project>
Application.class
#SpringBootApplication
#EnableTransactionManagement
#EntityScan("projectone.entities")
public class Application {
public static void main(String[] args) {
//For Starting application
ApplicationContext applicationContext=SpringApplication.run(Application.class, args);
}
}
Database Configuration file:
#Configuration
#EnableJpaRepositories(basePackages = {"projectone.mysql"},
entityManagerFactoryRef = "dbEntityManager",
transactionManagerRef = "dbTransactionManager")
#EnableTransactionManagement
public class DatabaseConfiguration {
#Autowired
private Environment env;
#Bean
#Primary
public LocalContainerEntityManagerFactoryBean dbEntityManager() {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dbDatasource());
em.setPackagesToScan(new String[]{"projectone.mysql"});
em.setPersistenceUnitName("dbEntityManager");
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
HashMap<String, Object> properties = new HashMap<>();
properties.put("hibernate.dialect",env.getProperty("hibernate.dialect"));
properties.put("hibernate.show-sql",env.getProperty("jdbc.show-sql"));
em.setJpaPropertyMap(properties);
return em;
}
#Primary
#Bean
public DataSource dbDatasource() {
DriverManagerDataSource dataSource
= new DriverManagerDataSource();
dataSource.setDriverClassName(
env.getProperty("spring.datasource.driverClassName"));
dataSource.setUrl(env.getProperty("spring.datasource.url"));
dataSource.setUsername(env.getProperty("spring.datasource.username"));
dataSource.setPassword(env.getProperty("spring.datasource.password"));
return dataSource;
}
#Primary
#Bean
public PlatformTransactionManager dbTransactionManager() {
JpaTransactionManager transactionManager
= new JpaTransactionManager();
transactionManager.setEntityManagerFactory(
dbEntityManager().getObject());
return transactionManager;
}
}
I tried minimal configuration by removing the database configuration class. After that my application is not running and I am getting Person is not a managed Bean error.
If I use only #SpringBootApplication annotation then I am getting following Exception:
It is throwing
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'mappingController': Unsatisfied dependency expressed through field 'branchService';
nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'branchServiceImplementaion': Unsatisfied dependency expressed through field 'branchRepository';
nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'branchRepository': Unsatisfied dependency expressed through method 'setSession' parameter 0;
nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.data.neo4j.transaction.SharedSessionCreator#0': Cannot resolve reference to bean 'sessionFactory' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in class path resource [org/springframework/boot/autoconfigure/data/neo4j/Neo4jDataAutoConfiguration.class]: Bean instantiation via factory method failed;
nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.neo4j.ogm.session.SessionFactory]: Factory method 'sessionFactory' threw exception; nested exception is NullPointerException

Finally I found the mistake:
#Bean
public PlatformTransactionManager dbTransactionManager() {
JpaTransactionManager transactionManager
= new JpaTransactionManager();
transactionManager.setEntityManagerFactory(
dbEntityManager().getObject());
return transactionManager;
}
This section has mistake that caused the above issue.
change #Bean to #Bean(name="transactionManager") and this solved the issue.

I had the same issue, but I was missing the transactionManagerRef = "dbTransactionManager" configuration in #EnableJpaRepositories

resolve: to change a name of function from:
public PlatformTransactionManager dbTransactionManager(){}
to:
public PlatformTransactionManager transactionManager(){}

Checke transactionManager this name JPAConfig class.
#Bean
public PlatformTransactionManager transactionManager(EntityManagerFactory emf){
return new JpaTransactionManager(emf);
}

I had the same problem and I noticed that there is an extra space where while specifying the transaction-manager as specified in the image.

Related

SpringBoot - Unsatisfied dependency expressed through field

I was trying for CRUD services using springboot with mongodb.
Getting error while running main application.
ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'productController': Unsatisfied dependency expressed through field 'productServiceImpl'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.cts.eaution.impl.ProductServiceImpl' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
Controller class :
#RestController
#RequestMapping("/e-auction/api/v1/seller/")
public class ProductController {
#Autowired
public ProductServiceImpl productServiceImpl;
/* #Autowired
public ProductRepository productRepository;
*/
#GetMapping("/show-bids")
public List<Product> getAllProducts() {
System.out.println("Hello Product...");
return productServiceImpl.findAll();
//return productRepository.findAll();
}
}
ServiceImpl class :
class ProductServiceImpl implements ProductService {
#Autowired
private ProductRepository productRepository;
#Override
public List<Product> findAll() {
return productRepository.findAll();
}
}
Service interface :
#Service
public interface ProductService {
List<Product> findAll();
}
Repository interface :
public interface ProductRepository extends MongoRepository<Product, String> {
}
Pom xml :
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<!-- <version>2.7.5</version> -->
<version>2.6.13</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.cts</groupId>
<artifactId>eauction</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>eauction</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
I tried multiple option by adding annotation like (service, repository, component, componentscan) non of this solve the problem.
application properties :
#server
server.port=8082
spring.data.mongodb.host=localhost
spring.data.mongodb.port=27017
spring.data.mongodb.database=productdb
Full Error logs :
Error creating bean with name 'productController': Unsatisfied dependency expressed through field 'productService'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'productServiceImpl': Unsatisfied dependency expressed through field 'productRepository'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'productRepository' defined in com.cts.eauction.repository.ProductRepository defined in #EnableMongoRepositories declared on MongoRepositoriesRegistrar.EnableMongoRepositoriesConfiguration: Cannot resolve reference to bean 'mongoTemplate' while setting bean property 'mongoOperations'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'mongoTemplate' defined in class path resource [org/springframework/boot/autoconfigure/data/mongo/MongoDatabaseFactoryDependentConfiguration.class]: Unsatisfied dependency expressed through method 'mongoTemplate' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mongoDatabaseFactory' defined in class path resource [org/springframework/boot/autoconfigure/data/mongo/MongoDatabaseFactoryConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.data.mongodb.core.MongoDatabaseFactorySupport]: Factory method 'mongoDatabaseFactory' threw exception; nested exception is java.lang.IllegalArgumentException: Database name must not contain slashes, dots, spaces, quotes, or dollar signs!
You have to place the #Service annotation on the implementation and not on the interface in order to make it autodetected by the component scan. Like this:
#Service
class ProductServiceImpl implements ProductService {
#Autowired
private ProductRepository productRepository;
#Override
public List<Product> findAll() {
return productRepository.findAll();
}
}
Also you should ask for a bean of the interface type and not the implementation in your controller:
#RestController
#RequestMapping("/e-auction/api/v1/seller/")
public class ProductController {
#Autowired
public ProductService productService;
}
This way you can have different implementations of the same interface, also you should not use field injection unless you have a good reason to use it.
If the above solution didn't work then another way you can try is by putting -
#ComponentScan(basePackages = {"com.package.class", "com.package.anotherClass"})
in your main application class.
This will scan all your classes present inside the packages.

Spring Boot set up Two Datasources gives Autoconfiguration error

I'm trying to configure two datasources in my spring boot app but by doing that I'm not sure if the Autoconfiguration option of spring should be turn off or if I'm missing some code.
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>pe.com.test</groupId>
<artifactId>Dashboard</artifactId>
<version>1.0.0</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.oracle.ojdbc</groupId>
<artifactId>ojdbc8</artifactId>
<version>19.3.0.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
application.properties
# Oracle settings
#DB1
db1.datasource.url=jdbc:oracle:thin:#192.168.1.2:1521:DB1
db1.datasource.username=test
db1.datasource.password=abc123
db1.datasource.driver.class=oracle.jdbc.driver.OracleDriver
#DB2
db2.datasource.url=jdbc:oracle:thin:#192.168.1.3:1521:DB2
db2.datasource.username=test
db2.datasource.password=abc123
db2.datasource.driver.class=oracle.jdbc.driver.OracleDriver
My config class.
#Configuration
public class DataSourceConfiguration {
#Bean
#Primary
#ConfigurationProperties("db1.datasource")
public DataSource db1Ds() {
return DataSourceBuilder.create().build();
}
#Bean
#ConfigurationProperties("db2.datasource")
public DataSource db2Ds() {
return DataSourceBuilder.create().build();
}
#Bean
#Autowired
#Primary
DataSourceTransactionManager db1Tm(#Qualifier("db1Ds") DataSource dataSource) {
DataSourceTransactionManager dstm = new DataSourceTransactionManager(dataSource);
return dstm;
}
#Bean
#Autowired
DataSourceTransactionManager db2Tm(#Qualifier("db2Ds") DataSource dataSource) {
DataSourceTransactionManager dstm = new DataSourceTransactionManager(dataSource);
return dstm;
}
}
I know that since I'm changing the default properties for autoconfiguring the database spring.datasource when starting the app It should give an error.
2020-04-04 16:02:25.654 WARN 15076 --- [ main] s.c.a.AnnotationConfigApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaConfiguration': Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Hikari.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.zaxxer.hikari.HikariDataSource]: Factory method 'dataSource' threw exception; nested exception is org.springframework.boot.autoconfigure.jdbc.DataSourceProperties$DataSourceBeanCreationException: Failed to determine a suitable driver class
2020-04-04 16:02:25.665 INFO 15076 --- [ main] ConditionEvaluationReportLoggingListener :
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2020-04-04 16:02:25.667 ERROR 15076 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter :
***************************
APPLICATION FAILED TO START
***************************
Description:
Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.
Reason: Failed to determine a suitable driver class
Action:
Consider the following:
If you want an embedded database (H2, HSQL or Derby), please put it on the classpath.
If you have database settings to be loaded from a particular profile you may need to activate it (no profiles are currently active).
Process finished with exit code 1
I can bypass these error just by turning off spring autoconfiguration.
spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration, org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration
What I want to know if I'm on the right path by turning DataSourceAutoConfiguration off or if I'm missing some other configuration in order to make autoconfigure work.
Better try with these database properties and configurations
#DB1
spring.db1-datasource.url=jdbc:oracle:thin:#192.168.1.2:1521:DB1
spring.db1-datasource.username=test
spring.db1-datasource.password=abc123
spring.db1-datasource.driver.class=oracle.jdbc.driver.OracleDriver
#DB2
spring.db2-datasource.url=jdbc:oracle:thin:#192.168.1.3:1521:DB2
spring.db2-datasource.username=test
spring.db2-datasource.password=abc123
spring.db2-datasource.driver.class=oracle.jdbc.driver.OracleDriver
#Configuration
public class DataSourceConfiguration {
#Bean
#Primary
#ConfigurationProperties(prefix="spring.db1-datasource")
public DataSource db1Ds() {
return DataSourceBuilder.create().build();
}
#Bean
#ConfigurationProperties(prefix="spring.db2-datasource")
public DataSource db2Ds() {
return DataSourceBuilder.create().build();
}
#Bean
#Autowired
#Primary
DataSourceTransactionManager db1Tm(#Qualifier("db1Ds") DataSource dataSource) {
DataSourceTransactionManager dstm = new DataSourceTransactionManager(dataSource);
return dstm;
}
#Bean
#Autowired
DataSourceTransactionManager db2Tm(#Qualifier("db2Ds") DataSource dataSource) {
DataSourceTransactionManager dstm = new DataSourceTransactionManager(dataSource);
return dstm;
}
}

Why does Spring Boot app start when two #Bean methods are present for restTemplate

I have this dependency:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.0.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
And I have this config:
#Configuration
public class AppConfig {
#Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
#Bean
public RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder) {
return restTemplateBuilder
.setConnectTimeout(ofMillis(3000))
.setReadTimeout(ofMillis(3000))
.build();
}
}
I wonder why Spring does not fail on start. It never inits first restTemplate but inits second one. I would expect Spring to fail.
This is a valid case, you are defining two bean definitions with same name of same bean, then the last bean defined will replace then first one bean defined.
If you want to an exception is thrown when two beans are defined by same name then you can configure by using setAllowBeanDefinitionOverriding(boolean allowBeanDefinitionOverriding) method from DefaultListableBeanFactory is who overrides whether it should be allowed to override bean definitions by registering a different definition with the same name.

Spring test: ApplicationContext configuration classes (spring data mongodb)

I only want to test mongo related code. This is my test code snippet:
#RunWith(SpringRunner.class)
#ContextConfiguration(classes = {MongoConfig.class})
#SpringBootTest
public class ModelTest {
#Autowired
private MongoTemplate mongoTemplate;
As you can see I'm using #ContextConfiguration in order to only load Mongo related configuration:
#Configuration
public class MongoConfig {
#Bean
public CustomConversions customConversions(){
List<Converter<?, ?>> converters = new ArrayList<Converter<?, ?>>();
converters.add(new ReferenceWriterConverter());
return new MongoCustomConversions(converters);
}
}
As you can see it's only intented to load custom converters are going to be used by mongoTemplate in order to serialize objects to mongodb database.
Also, src/test/resources/application.properties is:
spring.data.mongodb.host: localhost
spring.data.mongodb.port: 27017
The problem is that when I'm trying to run test it's getting me an Unsatisfied dependency expressed through field 'mongoTemplate':
UnsatisfiedDependencyException: Error creating bean with name 'net.gencat.transversal.repositori.digital.mongo.ModelTest': Unsatisfied dependency expressed through field 'mongoTemplate'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.data.mongodb.core.MongoTemplate' available
Related project dependencies:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
Any ideas?
Seems issue you are trying to load custom mongo configuration #Bean client here or extend AbstractMongoConfiguration.
change your database name here instead of demo
#Configuration
public class MongoConfig extends AbstractMongoConfiguration {
#Override
protected String getDatabaseName() {
return "demo";
}
#Override
public MongoClient mongoClient() {
return new MongoClient("localhost", 27017);
}
#Bean
public CustomConversions customConversions(){
List<Converter<?, ?>> converters = new ArrayList<Converter<?, ?>>();
converters.add(new ReferenceWriterConverter());
return new MongoCustomConversions(converters);
}
}

Spring boot - Data Source configuration

Am using Spring Boot version 1.2.7 in my project. Planning to use Spring Data JPA and trying to setup Universal connection pool to setup Datasource for mysql JDBC.
Am getting the following error and unable to setup Datasource.
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private javax.sql.DataSource org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration.dataSource; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [javax.sql.DataSource] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1210)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:368)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1119)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1014)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:504)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:956)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:747)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:117)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:689)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:321)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:969)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:958)
at mymantri.MymantriApplication.main(MymantriApplication.java:13)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private javax.sql.DataSource org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration.dataSource; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [javax.sql.DataSource] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:561)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331)
... 25 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [javax.sql.DataSource] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1301)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1047)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:942)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:533)
... 27 more
My pom.xml,
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.test</groupId>
<artifactId>test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>test</name>
<description>Test</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.2.7.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<start-class>test.TestApplication</start-class>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jersey</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
</dependency>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ucp</artifactId>
<version>11.2.0.3</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
<version>4.4</version>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.4</version>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
</dependency>
<dependency>
<groupId>com.eaio.uuid</groupId>
<artifactId>uuid</artifactId>
<version>3.2</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
<version>1.9.13</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
<dependency>
<groupId>net.sf.json-lib</groupId>
<artifactId>json-lib</artifactId>
<version>2.4</version>
<classifier>jdk15</classifier>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-parent</artifactId>
<version>Angel.SR3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
TestApplication.java,
#SpringBootApplication(exclude = { DataSourceAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class, VelocityAutoConfiguration.class })
public class TestApplication {
public static void main(String[] args) {
SpringApplication.run(TestApplication.class, args);
}
}
application-dev.properties,
application.datasource.driverClassName=com.mysql.jdbc.jdbc2.optional.MysqlDataSource
application.datasource.url=jdbc:mysql://localhost:3306/mymantri
application.datasource.username=root
application.datasource.password=root
application.datasource.initialSize=5
application.datasource.maxPoolSize=5
application.datasource.minPoolSize=5
hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
spring.jpa.properties.hibernate.dialect= org.hibernate.dialect.MySQL5Dialect
DataSource class,
#Configuration
#EnableTransactionManagement
#EnableJpaRepositories(entityManagerFactoryRef = "testEntityManagerFactory", transactionManagerRef = "testTransactionManager", basePackages = { "com.mymantri.web.repository"})
public class ApplicationDataSource {
/** The Constant LOGGER. */
private static final Logger LOGGER = LoggerFactory
.getLogger(ApplicationDataSource.class);
/** The Constant TEST_SQL. */
private static final String TEST_SQL = "select 1 from dual";
/** The pooled data source. */
private PoolDataSource pooledDataSource;
/** The environment. */
private Environment environment;
/** The Constant CONNECTION_WAIT_TIMEOUT_SECS. */
private static final int CONNECTION_WAIT_TIMEOUT_SECS = 300;
/**
* Data source.
*
* #return the pool data source
*/
#Bean(name = "testDataSource")
#Primary
public PoolDataSource testDataSource() {
this.pooledDataSource = PoolDataSourceFactory.getPoolDataSource();
final String databaseDriver = environment
.getRequiredProperty("application.datasource.driverClassName");
final String databaseUrl = environment
.getRequiredProperty("application.datasource.url");
final String databaseUsername = environment
.getRequiredProperty("application.datasource.username");
final String databasePassword = environment
.getRequiredProperty("application.datasource.password");
final String initialSize = environment
.getRequiredProperty("application.datasource.initialSize");
final String maxPoolSize = environment
.getRequiredProperty("application.datasource.maxPoolSize");
final String minPoolSize = environment
.getRequiredProperty("application.datasource.minPoolSize");
try {
pooledDataSource.setConnectionFactoryClassName(databaseDriver);
pooledDataSource.setURL(databaseUrl);
pooledDataSource.setUser(databaseUsername);
pooledDataSource.setPassword(databasePassword);
pooledDataSource.setInitialPoolSize(Integer.parseInt(initialSize));
pooledDataSource.setMaxPoolSize(Integer.parseInt(maxPoolSize));
pooledDataSource.setMinPoolSize(Integer.parseInt(minPoolSize));
pooledDataSource.setSQLForValidateConnection(TEST_SQL);
pooledDataSource.setValidateConnectionOnBorrow(Boolean.TRUE);
pooledDataSource
.setConnectionWaitTimeout(CONNECTION_WAIT_TIMEOUT_SECS);
// pooledDataSource.setConnectionPoolName(poolName);
} catch (NumberFormatException e) {
LOGGER.error("Unable to parse passed numeric value", e);
} catch (SQLException e) {
LOGGER.error("exception creating data pool", e);
}
LOGGER.info("Setting up datasource for user:{} and databaseUrl:{}",
databaseUsername, databaseUrl);
return this.pooledDataSource;
}
#Bean(name = "testEntityManagerFactory")
public EntityManagerFactory entityManagerFactory() {
LocalContainerEntityManagerFactoryBean lef = new LocalContainerEntityManagerFactoryBean();
JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
lef.setDataSource(myMantriDataSource());
lef.setJpaVendorAdapter(vendorAdapter);
lef.setPackagesToScan("com.mymantri.web.domain");
lef.setJpaProperties(additionalProperties());
lef.setPersistenceUnitName("myMantriPersistenceUnit");
lef.afterPropertiesSet();
return lef.getObject();
}
#Bean(name = "testTransactionManager")
public PlatformTransactionManager transactionManager() {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory());
return transactionManager;
}
Properties additionalProperties() {
Properties properties = new Properties();
properties.setProperty("hibernate.dialect",
"org.hibernate.dialect.MySQL5Dialect");
properties.setProperty("hibernate.enable_lazy_load_no_trans",
"true");
properties.setProperty("hibernate.show_sql","true");
return properties;
}
/**
* Sets the environment.
*
* #param environment
* the new environment
*/
#Autowired
public void setEnvironment(Environment environment) {
this.environment = environment;
}
}
Not sure, what is wrong with this config. Am i missing anything in the SpringBootConfig config.
Try to change data source registration method signature:
#Bean
public DataSource dataSource() {
BTW, it's not good idea to have local variables in configuration class. You have environment and pooledDataSource. Remove these class variables and create them locally in methods + pass them to Spring IoC container via #Bean annotation.
I suggest to change your configuration class at least this way:
#Configuration
#EnableTransactionManagement
#EnableJpaRepositories(entityManagerFactoryRef = "testEntityManagerFactory", transactionManagerRef = "testTransactionManager", basePackages = { "com.mymantri.web.repository"})
public class ApplicationDataSource {
/** The Constant LOGGER. */
private static final Logger LOGGER = LoggerFactory
.getLogger(ApplicationDataSource.class);
/** The Constant TEST_SQL. */
private static final String TEST_SQL = "select 1 from dual";
/** The Constant CONNECTION_WAIT_TIMEOUT_SECS. */
private static final int CONNECTION_WAIT_TIMEOUT_SECS = 300;
/**
* Data source.
*
* #return the pool data source
*/
#Bean
public DataSource dataSource(Environment environment) {
PoolDataSource pooledDataSource = PoolDataSourceFactory.getPoolDataSource();
final String databaseDriver = environment
.getRequiredProperty("application.datasource.driverClassName");
final String databaseUrl = environment
.getRequiredProperty("application.datasource.url");
final String databaseUsername = environment
.getRequiredProperty("application.datasource.username");
final String databasePassword = environment
.getRequiredProperty("application.datasource.password");
final String initialSize = environment
.getRequiredProperty("application.datasource.initialSize");
final String maxPoolSize = environment
.getRequiredProperty("application.datasource.maxPoolSize");
final String minPoolSize = environment
.getRequiredProperty("application.datasource.minPoolSize");
try {
pooledDataSource.setConnectionFactoryClassName(databaseDriver);
pooledDataSource.setURL(databaseUrl);
pooledDataSource.setUser(databaseUsername);
pooledDataSource.setPassword(databasePassword);
pooledDataSource.setInitialPoolSize(Integer.parseInt(initialSize));
pooledDataSource.setMaxPoolSize(Integer.parseInt(maxPoolSize));
pooledDataSource.setMinPoolSize(Integer.parseInt(minPoolSize));
pooledDataSource.setSQLForValidateConnection(TEST_SQL);
pooledDataSource.setValidateConnectionOnBorrow(Boolean.TRUE);
pooledDataSource
.setConnectionWaitTimeout(CONNECTION_WAIT_TIMEOUT_SECS);
// pooledDataSource.setConnectionPoolName(poolName);
} catch (NumberFormatException e) {
LOGGER.error("Unable to parse passed numeric value", e);
} catch (SQLException e) {
LOGGER.error("exception creating data pool", e);
}
LOGGER.info("Setting up datasource for user:{} and databaseUrl:{}",
databaseUsername, databaseUrl);
return pooledDataSource;
}
#Bean
public EntityManagerFactory entityManagerFactory() {
LocalContainerEntityManagerFactoryBean lef = new LocalContainerEntityManagerFactoryBean();
JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
lef.setDataSource(myMantriDataSource());
lef.setJpaVendorAdapter(vendorAdapter);
lef.setPackagesToScan("com.mymantri.web.domain");
lef.setJpaProperties(additionalProperties());
lef.setPersistenceUnitName("myMantriPersistenceUnit");
lef.afterPropertiesSet();
return lef.getObject();
}
#Bean
public PlatformTransactionManager transactionManager() {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory());
return transactionManager;
}
Properties additionalProperties() {
Properties properties = new Properties();
properties.setProperty("hibernate.dialect",
"org.hibernate.dialect.MySQL5Dialect");
properties.setProperty("hibernate.enable_lazy_load_no_trans",
"true");
properties.setProperty("hibernate.show_sql","true");
return properties;
}
}
Moving the Application to com.XXXXXX.web package works.
com.XXXXXX.web.domain - for domain classes
com.XXXXXX.web.repository - for repository classes
The default annotation scanning occurs based on the Application class package name.

Resources