Spring Error creating bean with name 'covidController' defined in file - java

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.

Related

How to exclude #EnableJpaRepositories from test?

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

SpringBoot UnsatisfiedDependencyException

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.

Can't run test on spring boot application because of injection of persistence dependencies failed

I have my java spring boot application and I'd like to write some tests using mockmvc; so this is the testing class:
#RunWith(SpringRunner.class)
#WebMvcTest(controllers = {IndexController.class})
#ComponentScan(basePackages={"com.sherlock.discoteque"})
#EnableJpaRepositories("com.sherlock.discoteque.repository")
#EntityScan(basePackages={"com.sherlock.discoteque"})
public class DiscotequeApplicationTests {
private MockMvc mockMvc;
#Autowired
private WebApplicationContext webApplicationContext;
#Before
public void setup() {
this.mockMvc = MockMvcBuilders.standaloneSetup(webApplicationContext).build();
}
#Test
public void testAlbumInfo() throws Exception{
this.mockMvc.perform(get("/")).andExpect(status().isOk());
}
}
but when I execute the code I have the following error message:
Field albumRepository in com.sherlock.discoteque.controller.AlbumController required a bean of type 'javax.persistence.EntityManagerFactory' that could not be found.
The injection point has the following annotations:
- #org.springframework.beans.factory.annotation.Autowired(required=true)
Action:
Consider defining a bean of type
'javax.persistence.EntityManagerFactory' in your configuration.
...
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'albumController': Unsatisfied
dependency expressed through field 'albumRepository'; nested exception
is org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'albumRepositoryImpl': Injection of
persistence dependencies failed; nested exception is
org.springframework.beans.factory.NoSuchBeanDefinitionException: No
qualifying bean of type 'javax.persistence.EntityManagerFactory'
available
Caused by: org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'albumRepositoryImpl': Injection of
persistence dependencies failed; nested exception is
org.springframework.beans.factory.NoSuchBeanDefinitionException: No
qualifying bean of type 'javax.persistence.EntityManagerFactory'
available
Which is weird, considering the fact that without the testing class everything works fine. This is the class AlbumRepositoryImpl
public class AlbumRepositoryImpl implements AlbumRepositoryCustom {
private final static String RECENT_ALBUMS_QUERY = "select * from album order by createdate desc limit ?";
#PersistenceContext
public EntityManager entityManager;
#Override
public List<Album> getRecentAlbums(int size) {
if(size<1){
throw new IllegalArgumentException();
}
Query query = entityManager.createNativeQuery(RECENT_ALBUMS_QUERY, Album.class);
query.setParameter(1, size);
return query.getResultList();
}
}
and inside the AlbumController I do have the attribute
#Autowired
private AlbumRepository albumRepository;
and I have the AlbumRepository interface as well (extended from JpaRepository). I really don't know what to do to make the web application running on test, could anybody help me?
In sample code , you are trying to autowire the context , however you have not provided the test configuration.
In your project you have defined JPA entity manager configuration , but in test file you are not providing that info. Spring won't be able to start the container till you don't provide the necessary configuration in test class.
You can take an idea from https://www.petrikainulainen.net/programming/spring-framework/integration-testing-of-spring-mvc-applications-configuration/
Try to set spring boot profile with annotation - #ActiveProfiles("you_profile")

How can I use YAML properties with constructor injection in Spring Boot?

I know this should be a piece of cake but I'm just not getting anywhere.
In my Spring Boot app, in the application.yml file, I have an entry like so:
some:
constructor:
property: value
And I have a spring service (this is fake but demonstrates the problem):
package somepackage;
#Service
public class DummyService {
public DummyService(#Value("${some.constructor.property}") String path) {}
}
Startup fails, though:
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'dummyService' defined in file [...(the class
file)... ]: Instantiation of bean failed; nested exception is
org.springframework.beans.BeanInstantiationException: Failed to
instantiate [somepackage.DummyService]: No default constructor found;
nested exception is java.lang.NoSuchMethodException:
somepackage.DummyService.()
How can I convince Spring that it should use the non-empty constructor, and it should get that constructor parameter from the YAML file? Note: I'm not using any XML bean config files or anything, and would prefer not to.
Just put the #Autowired annotation on your constructor.
#Autowired
public DummyService(#Value("${some.constructor.property}") String path) {}
And just in case someone else is trying to do this in Scala -- which is what I was really trying to do, but wanted to get the answer in Java before trying it with Scala -- this works:
#Service
class DummyService #Autowired()(#Value("${some.constructor.property}") val path: String) {
}
This is covered in this SO case for scala constructor autowiring.

Autowiring Embedded Elastic with Spring

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.

Categories

Resources