SpringBoot - Unsatisfied dependency expressed through field - spring

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.

Related

UnsatisfiedDependencyException: Error creating bean with name 'sendController'

I have followed this tutorial to send message to an azure service queue: https://learn.microsoft.com/en-us/azure/java/spring-framework/configure-spring-boot-starter-java-app-with-azure-service-bus
to my existing spring boot app but I get the following error:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'sendController': Unsatisfied dependency expressed through field 'jmsTemplate'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'jmsTemplate' defined in class path resource [com/microsoft/azure/spring/autoconfigure/jms/ServiceBusJMSAutoConfiguration.class]: Unsatisfied dependency expressed through method 'jmsTemplate' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jmsConnectionFactory' defined in class path resource [com/microsoft/azure/spring/autoconfigure/jms/ServiceBusJMSAutoConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.jms.ConnectionFactory]: Factory method 'jmsConnectionFactory' threw exception; nested exception is java.lang.NullPointerException
User Class:
package com.proyecto.demo.domain;
import com.microsoft.azure.spring.data.cosmosdb.core.mapping.Document;
import com.microsoft.azure.spring.data.cosmosdb.core.mapping.PartitionKey;
import java.io.Serializable;
import org.springframework.data.annotation.Id;
#Document(collection = "tUser")
public class User implements Serializable {
private static final long serialVersionUID = -295422703255886286L;
#Id
private String id;
private String firstName;
#PartitionKey
private String lastName;
private String address;
public User(String id, String firstName, String lastName, String address) {
this.id = id;
this.firstName = firstName;
this.lastName = lastName;
this.address = address;
}
public User(String firstName) {
this.firstName = firstName;
}
public User() {
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
#Override
public String toString() {
return String.format("%s %s, %s", firstName, lastName, address);
}
}
Controller Class:
package com.proyecto.demo.web;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.proyecto.demo.domain.User;
#RestController
public class SendController {
private static final String DESTINATION_NAME = "testqueue";
#Autowired
private JmsTemplate jmsTemplate;
#PostMapping("/messages")
public String postMessage(#RequestParam String message) {
jmsTemplate.convertAndSend(DESTINATION_NAME, new User(message));
return message;
}
}
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.2.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.proyecto</groupId>
<artifactId>FileUploaderProject</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>FileUploaderProject</name>
<description>FileUploader</description>
<properties>
<java.version>1.8</java.version>
<azure.version>2.2.4</azure.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-servicebus-jms-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-cosmosdb-spring-boot-starter</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-jms -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-spring-boot-bom</artifactId>
<version>${azure.version}</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>
adding the application properties it used it like a yml I removed all the sensitive information
azure:
cosmosdb:
database: testdb
key:
uri: https://testcosmosql.documents.azure.com:443/
spring:
jms:
servicebus:
connection-string:
idle-timeout: 1800000
Here is some of the stack trace:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'sendController': Unsatisfied dependency expressed through field 'jmsTemplate'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'jmsTemplate' defined in class path resource [com/microsoft/azure/spring/autoconfigure/jms/ServiceBusJMSAutoConfiguration.class]: Unsatisfied dependency expressed through method 'jmsTemplate' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jmsConnectionFactory' defined in class path resource [com/microsoft/azure/spring/autoconfigure/jms/ServiceBusJMSAutoConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.jms.ConnectionFactory]: Factory method 'jmsConnectionFactory' threw exception; nested exception is java.lang.NullPointerException
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:643) ~[spring-beans-5.2.5.RELEASE.jar:5.2.5.RELEASE]
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:130) ~[spring-beans-5.2.5.RELEASE.jar:5.2.5.RELEASE]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:399) ~[spring-beans-5.2.5.RELEASE.jar:5.2.5.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1422) ~[spring-beans-5.2.5.RELEASE.jar:5.2.5.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:594) ~[spring-beans-5.2.5.RELEASE.jar:5.2.5.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517) ~[spring-beans-5.2.5.RELEASE.jar:5.2.5.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323) ~[spring-beans-5.2.5.RELEASE.jar:5.2.5.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.2.5.RELEASE.jar:5.2.5.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321) ~[spring-beans-5.2.5.RELEASE.jar:5.2.5.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-5.2.5.RELEASE.jar:5.2.5.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:882) ~[spring-beans-5.2.5.RELEASE.jar:5.2.5.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:878) ~[spring-context-5.2.5.RELEASE.jar:5.2.5.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550) ~[spring-context-5.2.5.RELEASE.jar:5.2.5.RELEASE]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:141) ~[spring-boot-2.2.6.RELEASE.jar:2.2.6.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:747) ~[spring-boot-2.2.6.RELEASE.jar:2.2.6.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) ~[spring-boot-2.2.6.RELEASE.jar:2.2.6.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) ~[spring-boot-2.2.6.RELEASE.jar:2.2.6.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226) ~[spring-boot-2.2.6.RELEASE.jar:2.2.6.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1215) ~[spring-boot-2.2.6.RELEASE.jar:2.2.6.RELEASE]
at com.proyecto.demo.FileUploaderProjectApplication.main(FileUploaderProjectApplication.java:11) ~[classes/:na]
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'jmsTemplate' defined in class path resource [com/microsoft/azure/spring/autoconfigure/jms/ServiceBusJMSAutoConfiguration.class]: Unsatisfied dependency expressed through method 'jmsTemplate' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jmsConnectionFactory' defined in class path resource [com/microsoft/azure/spring/autoconfigure/jms/ServiceBusJMSAutoConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.jms.ConnectionFactory]: Factory method 'jmsConnectionFactory' threw exception; nested exception is java.lang.NullPointerException
I tried different solution like disable: ActiveMQAutoConfiguration and some others that i found but none of them.
I tried a lot of the solution I found on stack, that this is related with the fact that jms is not instantiated. I added JMS to my pom file.
I also tried updating the version, I have tried a lot of different solutions but it is still not working
I tried this one as well:
UnsatisfiedDependencyException: Error creating bean with name
Thanks a lot for all your help
The problem you're having is that Spring isn't able to instantiate the #Autowired classes you've specified.
Error creating bean with name 'jmsConnectionFactory' defined in class path resource
Means, JmsConnectionFactory bean is not instantiated. I didn't find
JMS library in your pom.xml.
You can include the JMS library by adding the following to your pom.xml
<dependency>
<groupId>javax.jms</groupId>
<artifactId>javax.jms-api</artifactId>
<version>2.0.1</version>
</dependency>
Then spring can instantiate JmsConnectionFactory bean.
thanks a lot for your help Arthur was right there was something wrong with the connection string I had an connection-string: '"connstirng'

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;
}
}

No bean named 'transactionManager' available

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.

No property saveAll found for type

I recently started using ReactiveCouchbaseRepository (spring-data-couchbase - 3.0.0.M2, spring-boot-starter-parent - 2.0.0.M2) in one of our projects.
I referred to unpublished doc from here and setup the project but I am getting the following error.
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dummyRepository': Invocation of init method failed; nested exception is org.springframework.data.mapping.PropertyReferenceException: No property saveAll found for type Dummy!
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1717) ~[spring-beans-5.0.0.RC2.jar:5.0.0.RC2]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:581) ~[spring-beans-5.0.0.RC2.jar:5.0.0.RC2]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:498) ~[spring-beans-5.0.0.RC2.jar:5.0.0.RC2]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:305) ~[spring-beans-5.0.0.RC2.jar:5.0.0.RC2]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:233) ~[spring-beans-5.0.0.RC2.jar:5.0.0.RC2]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:303) ~[spring-beans-5.0.0.RC2.jar:5.0.0.RC2]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:198) ~[spring-beans-5.0.0.RC2.jar:5.0.0.RC2]
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:250) ~[spring-beans-5.0.0.RC2.jar:5.0.0.RC2]
Here is the relevant information about setting up my project.
#Maven
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.M2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
...
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-couchbase</artifactId>
<version>3.0.0.M2</version>
</dependency>
#java
//Repository class
public interface DummyRepository extends ReactiveCouchbaseSortingRepository<Dummy, String> {
}
//Model class
public class Dummy {
#Id
private final String id;
#Field
private final String name;
#Field
private final String address;
...
}
//Java config class
#Configuration
#EnableReactiveCouchbaseRepositories
public class CouchbaseDatabaseConfig extends AbstractReactiveCouchbaseConfiguration {
...
}
Now, i did go through this and this but here i have no custom method written in the DummyRepository class.
Note that when I change from ReactiveCouchbaseSortingRepository to CouchbaseRepository, the things works fine.
Thanks for the help in advance.
It seems we just need to add the following dependency to have saveAll implementation in.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-couchbase</artifactId>
</dependency>
ps : thanks to Subhashni Balakrishnan to have answered it on couchbase forums - here
You should Add #Query on you method otherwise, the jpa will treat it as a property

Spring AOP Bean Injection Bug?

I've checked in the test project here: https://github.com/loesak/spring-aop-injection-bug
Given the following pom.xml:
<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>com.loesoft</groupId>
<artifactId>spring-aop-injection-bug</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<spring.framework.bom.version>4.2.0.RELEASE</spring.framework.bom.version>
<spring.retry.version>1.1.2.RELEASE</spring.retry.version>
<aspectj.aspectjweaver>1.8.7</aspectj.aspectjweaver>
<java.version>1.7</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-framework-bom</artifactId>
<version>${spring.framework.bom.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
<version>${spring.retry.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>${aspectj.aspectjweaver}</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<compilerArgument>-Xlint:all</compilerArgument>
<showWarnings>true</showWarnings>
<showDeprecation>true</showDeprecation>
</configuration>
</plugin>
</plugins>
</build>
</project>
and Spring configuration:
package com.loesoft.spring.aop.injection.bug;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.retry.annotation.EnableRetry;
import org.springframework.retry.annotation.Retryable;
#Configuration
#EnableRetry
public class Proof {
public static void main(String... args) {
final AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Proof.class);
context.registerShutdownHook();
}
#Bean
public BeanThing beanThing() {
return new BeanThing();
}
#Bean
#Autowired
public BeanNeedy beanNeedy(BeanThing beanThing) {
return new BeanNeedy(beanThing);
}
public static interface BeanInterface {
public void doSomething();
}
public static class BeanThing implements BeanInterface {
#Retryable
public void doSomething() {
System.out.println("BeanNeedingDependencies doing something");
}
}
public static class BeanNeedy {
private final BeanThing beanThing;
public BeanNeedy(BeanThing beanThing) {
this.beanThing = beanThing;
}
}
}
The following error is thrown by Spring:
Exception in thread "main" org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'beanNeedy' defined in com.loesoft.spring.aop.injection.bug.Proof: Unsatisfied dependency expressed through constructor argument with index 0 of type [com.loesoft.spring.aop.injection.bug.Proof$BeanThing]: : No qualifying bean of type [com.loesoft.spring.aop.injection.bug.Proof$BeanThing] 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 [com.loesoft.spring.aop.injection.bug.Proof$BeanThing] 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)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:464)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1123)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1018)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:510)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:305)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:301)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:196)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:772)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:834)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:537)
at org.springframework.context.annotation.AnnotationConfigApplicationContext.<init>(AnnotationConfigApplicationContext.java:84)
at com.loesoft.spring.aop.injection.bug.Proof.main(Proof.java:15)
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.loesoft.spring.aop.injection.bug.Proof$BeanThing] 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:1326)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1072)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:967)
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:813)
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:741)
... 14 more
I've tracked this down to the fact that the bean "beanThing" ends up being a JdkDynamicAopProxy because it has interfaces and when trying to find a matching bean as an autowired candidate when creating bean "beanNeedy", the code ends up in ResolvableType#isInstance which does not check the underlying type for the JDK proxy type and does not find the created bean "beanThing" of type "BeanThing".
I can get around this in two ways. The first by setting the #EnableRetry annotation field "proxyTargetClass" to "true" or by removing the interface on the class BeanThing.
Is this a bug or am I missing some information about Spring AOP that I am not aware of? In general, this doesn't seem right to me. I feel Spring should be able to determine the underlying type of the Proxy bean unless there is some technical reason as to why it cannot. And if there is a technical reason as to why the underlying type of the JDK proxy could not be determined, then maybe Spring should have some additional checks to help the developer figure out what is going on.
Keep in mind that this is not related to Spring Retry (thus not tagged) as I've been able to reproduce this problem with other annotations that require the underlying bean to be wrapped with an AOP proxy.
From the JDK Proxy javadocs:
A dynamic proxy class is a class that implements a list of interfaces
specified at runtime when the class is created
This means that the proxy can only implement the interfaces of the bean, but is not an instance of it. You cannot substitute the real class with the proxy, as you do not have the methods and variables of the class, just the methods of the proxy.
I can get around this in two ways. The first by setting the
#EnableRetry annotation field "proxyTargetClass" to "true" or by
removing the interface on the class BeanThing.
If you set proxyTargetClass to true, instead of a JDK Proxy, Spring will create a CGLIB class (this also happens when the class has no interfaces, because you cannot create a JDK Proxy without interfaces).
With CGLIB, a subclass of your bean is dinamically created that intercepts the method calls.
The CGLIB proxy is a BeanThing, because it inherits from it. The JDK Proxy is not a BeanThing, because it just implements its interfaces.
There is a third way to workaround your problem: instead of injecting the BeanThing class, inject the interface it implements (BeanInterface).
#Bean
public BeanInterface beanThing() {
return new BeanThing();
}
// .....
public static class BeanNeedy {
private final BeanInterface beanThing;
public BeanNeedy(BeanInterface beanThing) {
this.beanThing = beanThing;
}
}
Configuration
In order to enable CGLIB, you can use the #EnableAspectJAutoProxy annotation with the proxyTargetClass set to true in one of your configuration classes.
#Configuration
#EnableAspectJAutoProxy(proxyTargetClass = true)
public class OneOfYourGlobalConfigConfigs {
}

Resources