I'm getting the UnsatisfiedDependencyException exception when starting my SpringBoot Application, my main class has these annotations
#SpringBootApplication
#ComponentScan(basePackages = { "com.xxx.yyy" })
#EntityScan("com.xxx.zzzz")
public class App {
}
My entities annotated with #Entity were included as external jars to classpath, my repository class has the #Repository annotation
#Repository
public interface ClassRepository extends JpaRepository<XXX, BigInteger> {
}
My entity is declared as
#Entity
#Table(name = "MyTable")
public class MyEntityClass implements Serializable {
}
The follow is part of the stacktrace
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'XXXController': Unsatisfied dependency expressed through field 'repositoryXXX';
nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'xxxRepository': Invocation of init method failed;
nested exception is java.lang.IllegalArgumentException: Not a managed type: class com.xxx.yyy.zzz.entities.MyClass
Solved, after different aproaches I've created a new jar file but "Add directory entries" option were selected, add the jar to the project and works fine. I guess without the selected option the application doesn't known the folders or packages included in the jar file.
Thanks to everyone.
Related
I'm working on two relative projects. One project is used to connect to postgresql and another project import the connector project as dependency to connect to postgresql. In connector project I used EntityManager to access to database.
In Repository class I use entity manager to get entity
#Transactional
#Repository
public class ConfigDetailRepository {
private EntityManager entityManager;
#Autowired
public ConfigDetailRepository(final EntityManager entityManager) {
this.entityManager = entityManager;
}
public void doSomething()
And in Service class I autowire repository
#Configurable
#Service
public class SampleService {
#Autowired
private ConfigDetailRepository configDetailRepository;
public class (){ configDetailRepository.doSomething()}
This connector project is workable and able to get data from database. In my second project I import the connector project and add this dependency in pom.xml
<dependency>
<groupId>package name</groupId>
<artifactId>package-id</artifactId>
<version>package-version</version>
</dependency>
And that's my Application.class and class import SampleService
#SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
#ComponentScan(basePackages = {"package name"})
public class CassandraTestApplication {
public static void main(String[] args) {
SpringApplication.run(CassandraTestApplication.class, args);
}
#Configurable
#Component
public class TestConnector {
#Autowired
SampleService sampleService;
public void doSomtehing() {
sampleService.doSomething();
}
}
When I run the project I got following error:
***************************
APPLICATION FAILED TO START
***************************
Description:
Parameter 0 of constructor in package.repository.ConfigDetailRepository required a bean of type 'javax.persistence.EntityManager' that could not be found.
The injection point has the following annotations:
- #org.springframework.beans.factory.annotation.Autowired(required=true)
java.lang.IllegalStateException: Failed to load ApplicationContext
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'testConnector': Unsatisfied dependency expressed through field 'sampleService'; nested exception is org.springframework.beans
.factory.UnsatisfiedDependencyException: Error creating bean with name 'sampleService': Unsatisfied dependency expressed through field 'configDetailRepository'; nested exception is org.springframework.beans.factory.UnsatisfiedDepende
ncyException: Error creating bean with name 'configDetailRepository' defined in URL [jar:file:/C:/Users/.m2/repository/com/connector/cassandra-db/0.0.1-SNAPSHOT/cassandra-db-0.0.1-SNAPSHOT.jar!/com/repository/ConfigDetailRepository.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying b
ean of type 'javax.persistence.EntityManager' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
I check the connector project and it can work. Then I tried exclude=HibernateJpaAutoConfiguration.class but that didn't work. Can anyone tell me why the entity manager cannot be created?
The problem is the exclude = {DataSourceAutoConfiguration.class}. With this you are excluding the configuration of the DataSource by Spring Boot. Unless you specify one yourself using an #Bean method this basically prevents you from doing all DB related work.
JPA requires access to your database and without a configured DataSource this will not be possible. Due to the missing DataSource Spring Boot will also not configure JPA. No JPA will lead to this error.
To fix, remove the exclude and provide the configuration for the database.
I have a main #SpringBootApplication which needs to scan a specific package in order to enable the JPA repositories, so I use #EnableJpaRepositories to specify that. Right now I'm implementing unit tests and I want to test the Controller component only, so I followed the tutorial in the official docs where they use #WebMvcTest(MyController.class) to test a controller with a service dependency.
The problem is that this is not working for me because it is trying to load the JpaRepositories that I specify in the main Spring Boot application (when I comment the #EnableJpaRepositories in the main class the test runs without problem).
I'm guessing I need to create a specific configuration for the test class so it can ignore the main configuration (since I only want to load the Controller and mock the service layer), but I don't know how to create such. I tried adding an empty configuration, but it is still failing with the same error:
#TestConfiguration
static class TestConfig {}
This is the error I get:
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'failureTaskHandler': Unsatisfied dependency expressed through field 'myManager'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'msgManager': Unsatisfied dependency expressed through field 'inboundManager'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'inboundManager': Unsatisfied dependency expressed through field 'messageRepository'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'messageRepository' defined in com.example.MessageRepository defined in #EnableJpaRepositories declared on MonitorApplication: Cannot create inner bean '(inner bean)#45e639ee' of type [org.springframework.orm.jpa.SharedEntityManagerCreator] while setting bean property 'entityManager'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#45e639ee': Cannot resolve reference to bean 'entityManagerFactory' while setting constructor argument; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'entityManagerFactory' available
And my test class:
#WebMvcTest(MyController.class)
public class MyControllerTest {
#Autowired private MockMvc mvc;
#MockBean private MyService service;
// Tests here
// #Test
// public void...
}
MyController class:
#RestController
#CrossOrigin
#RequestMapping("/api")
#Slf4j
public class MyController {
#Autowired private MyService service;
#PostMapping(value = "/search", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public #ResponseBody SearchResponse getOrders(#RequestBody SearchRequest orderSearchRequest) {
log.info("Receiving orders request...");
return service.getOrders(orderSearchRequest);
}
}
Quick solution
Remove #EnableJpaRepositories from your Spring Boot Application class. Use:
#SpringBootApplication
public class MainApplication {
}
in place of
#SpringBootApplication
#EnableJpaRepositories
public class MainApplication {
}
In this case Spring Boot will find Spring Data JPA on the classpath and uses auto-configuration to scan packages for the repositories.
Use #EnableJpaRepositories to scan a specific package
Use #NikolaiShevchenko solution (it is incorrect) with a separate configuration, but without explicit importing it, by #Import({ DataConfiguration.class }), (because tests will be explicitly import the configuration too) and let Spring Boot find your configuration during packages scan.
#SpringBootApplication
public class MainApplication {
}
#Configuration
#EnableJpaRepositories(basePackages = "com.app.entities")
public class JpaConfig {
}
Important
Don't forget to add basePackages property, if you put your configuration in a separate package.
Declare separate configuration
#Configuration
#EnableJpaRepositories
public class DataConfiguration { ... }
Import it into the application
#SpringBootApplication
#Import({ DataConfiguration.class })
public class MainApplication { ... }
but don't import into MyControllerTest
First of all, you may think/vote this question as a duplicate. Let me tell you, I have tried almost every possible solution on SO and not on SO.
I am using the Spring framework for a project and the project is based on a layered architecture. I have tried to fix an exception that is thrown when I start the Spring. I am trying to solve this for the last few days and I was not able to solve it. (I am new to spring)
I have three layers:
domain
persistence
rest
When I start the application, it throws me an error:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'covidController' defined in file [......./layered-architecture-spring/rest/target/classes/com/comp/rest/CovidController.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'covidRepository' defined in com.comp.persistence.CovidRepository defined in #EnableJpaRepositories declared on RestApp: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Failed to create query for method public abstract java.util.List com.comp.persistence.CovidRepository.fetchAllData()! No property fetchAllData found for type Covid!
Caused by: java.lang.IllegalArgumentException: Failed to create query for method public abstract java.util.List com.comp.persistence.CovidRepository.fetchAllData()! No property fetchAllData found for type Covid!
Caused by: org.springframework.data.mapping.PropertyReferenceException: No property fetchAllData found for type Covid!
at org.springframework.data.mapping.PropertyPath.<init>(PropertyPath.java:94) ~[spring-data-commons-2.3.0.RELEASE.jar:2.3.0.RELEASE]
My whole project on GitHub: https://github.com/Phoenix404/ssa-layered-assignment
#RestController
public class CovidController {
private final CovidRepository covidRepository;
public CovidController(CovidRepository cr) {
covidRepository = cr;
}
#GetMapping("/cdata")
public List<Covid> getList() {
return this.covidRepository.findByLocation("italy");
}
}
#Repository
public interface CovidRepository extends JpaRepository<Covid, Integer> {
List<Covid> fetchAllData();
List<Covid> findByDate(Date date);
List<Covid> findByLocation(String location);
}
CovidController is my Rest app controller inside the rest module. The CovidRepository is in the persistence module.
I am using the following annotations for scanning the classes as suggested on other SO but I am still getting the error:
#SpringBootApplication
#EnableJpaRepositories("com.comp.**persistence**")
#EntityScan(basePackages = {"com.comp.**"})
#ComponentScan(basePackages = {"com.comp.**"})
#SpringBootApplication
#EnableJpaRepositories("com.comp.persistenc*")
#EntityScan(basePackages = {"com.comp"})
#ComponentScan(basePackages = {"com.comp"})
#SpringBootApplication
#EnableJpaRepositories("com.comp.*")
#EntityScan(basePackages = {"com.comp.*"})
#ComponentScan(basePackages = {"com.comp.*"})
What am I doing wrong?
Thanks to #aniket-sahrawat, for solving the question.
The problem is solved, when I removed the methods from my covidRepository.
I'm trying to build a rest api with Spring and Embedded Elastic. I'm getting an NoSuchBeanDefinitionException when trying to start my application.
Currently, I have this for wiring the elastic db:
#Configuration
public class EsConfig {
Node node;
#Bean
public Client es() {
node = nodeBuilder().local(true).node();
return node.client();
}
(Destructor)
}
and in the controller:
#RestController
public class Controller {
#Autowired
public Client elasticSearchClient;
...
}
But when I start it up, I get this exception:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'controller': Injection of autowired dependencies failed;
nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: public org.elasticsearch.client.Client package.Controller.elasticSearchClient;
nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException:
No qualifying bean of type [org.elasticsearch.client.Client] 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)}
I've tried a few different annotations but I'm obviously way off.
No qualifying bean of type [some.Thing] means that spring knowns no class that is applicable for this interface.
Reasons for that can be
The class that has the #Bean method is not a #Configuration class
The #Configuration class is not picked up by the classpath component scanner.
Spring boot by default will only scan the child package hierarchy of the #SpringBootApplication. If you want to include code outside of that you can change the scanning behavior via the #ComponentScan annotation.
#SpringBootApplication
#ComponentScan(basePackageClasses = {MyApp.class, SomeOtherClassInARootPackage.class})
public class MyApp {
...
Would add the package (and sub packages) of some other class, while keeping the packages of the application scanned as well.
My code has this set up:
public class myResource() {
#Autowired
ImyHandler myHandler;
....
}
The next layer up contains my handler classes. I have two sets of classes, one is an interface class, and the other is the regular class, like:
public interface myHandler() {
public myObject modifyFunction();
}
and then my regular class looks like:
public class myHandler() {
....
}
However, when I build my project, I get this error:
Error creating bean with name 'myResource': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: ImyHandler
In my context-web.xml file, I declared:
<bean id="myHandler" class="myHandler" />
I'm not sure why I am getting this error, as I explicitly stated that the interface class is in my context. Does anyone understand why this is happening?
You also need to specify the package of the class in the bean that you want to create.