0

I'm a Spring noob and I'm struggling with it.

Basically before starting develop my Server with Spring in conjunction with JPA I tried to start a simple example just to get used to this framework. I've already get succeded in make Spring working with some frameworks as Log4J, Swagger and others. Now I'm trying to work with JPA and there are some points i can find out the solution.

I saw some blogs on how to develop with it and from all thousands options i choose to create my Repository Interfece and extend Repository<T, ID>. You can see my code bellow:

package com.example.model;
@Entity
public class Person {

    @Id
    public Integer id;

    public String name;

    public Person(){}
}

package com.example.repository;
public interface PersonRepository extends Repository<Person, Integer> {
    Collection<Person> findAll();
}


package com.example.controller;
@RestController
public class PersonController {

    @Autowired
    private PersonRepository repo;

    @RequestMapping(value = "/persons", method = RequestMethod.GET)
    public Collection<Person> getAll() {
        return repo.findAll();
    }
}

package com.example;
@SpringBootApplication
public class App {
    public static void main(String[] args) {
        SpringApplication.run(App.class, args);
    }
}

And I also have the application.properties file:

spring.datasource.platform=postgres
spring.datasource.url=jdbc:postgresql://localhost:5432/test_db
spring.datasource.username=test
spring.datasource.password=test
spring.datasource.driver-class-name=org.postgresql.Driver

When I put the server running I get the following exception:

: Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'personController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.example.repository.PersonRepository com.example.controllers.PersonController.repo; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.example.repository.PersonRepository] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: 
: Closing JPA EntityManagerFactory for persistence unit 'default'
: Stopping service Tomcat
: Application startup failed

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'personController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.example.repository.PersonRepository com.example.controllers.PersonController.repo; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.example.repository.PersonRepository] 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 created a Github Repository to share the code here.

Any clue about what am I doing wrong?

Bruno Dantas
  • 31
  • 1
  • 3
  • 9

4 Answers4

2

First thing here is why you need to implements the base interface Repository as doing so, you will not have usual CRUD operations. For such operations is better to implements CrudRepository. Since you implement CrudRepository no need to define a findAll() Method and many well known others you can find in doc mentioned.

Furthermore, when using @SpringBootApplication Spring boot use default values. If you see the @SpringBootApplication definition you will see that :

Many Spring Boot developers always have their main class annotated with @Configuration, @EnableAutoConfiguration and @ComponentScan. Since these annotations are so frequently used together (especially if you follow the best practices above), Spring Boot provides a convenient @SpringBootApplication alternative.

The @SpringBootApplication annotation is equivalent to using @Configuration, @EnableAutoConfiguration and @ComponentScan with their default attributes: [...]

That means when using default values for ComponentScan your packages sturctures shloud be as following :

  1. com.example.model -> your entities
  2. com.example.repositoriy -> your repositories
  3. com.example.controller -> controllers
  4. com.example -> MainApplication class

Here is an example for default project structure The main Application Class should be in higher level package then the others. Unless you have to specify packages location with @ComponentScan.

As you are beginner with the framework. I suggest you to always see classes definitions in official documentation.

UPDATE :

Here is an example from one of my spring boot projects

enter image description here

Also see this spring guide for JPA

Community
  • 1
  • 1
Hassam Abdelillah
  • 2,246
  • 3
  • 16
  • 37
1

Just annotate your interface with @Repository. And if that doesnt work try adding @EnableJPARepositories to the main class.

chetank
  • 392
  • 3
  • 17
  • 1
    With Repositories and EnableJpaRepositories i got a different exception. Exception Could not autowire field: private com.example.repository.PersonRepository com.example.controllers.PersonController.repo; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'personRepository': Invocation of init method failed; nested exception is java.lang.NoClassDefFoundError: org/springframework/data/repository/query/QueryByExampleExecutor – Bruno Dantas Apr 29 '16 at 18:27
  • Just follow this https://github.com/joshlong/bootiful-microservices/blob/master/bootiful-applications/reservation-service/src/main/java/com/example/ReservationServiceApplication.java – chetank Apr 29 '16 at 18:41
0

Try adding the @Repository annotation to your PersonRepository, that could be the reason it doesn't find it.

KrizD
  • 119
  • 5
0

You need to annotate your PersonRepository interface with @Respository, otherwise the spring context won't recognize it or create an implementation for it.

G. Stark
  • 1
  • 1