2

I'm learning Spring and things were going well but suddenly running into this issue where it cannot find a qualified bean. Hitting the wall, even in a new app I'm getting this.

Let me know if you need more, going to take a break! I must be missing something very simple.

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException:
  No qualifying bean of type [com.alco.repository.ContactRepository]
  found for dependency [com.alco.repository.ContactRepository]:
  expected at least 1 bean which qualifies as autowire candidate for this dependency.
  Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

My dependencies:

<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-rest</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-hateoas</artifactId>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</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-web</artifactId>
    </dependency>

    <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

Contact class:

package com.example.entity;

import java.io.Serializable;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@Entity
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
public class Contact implements Serializable {

private static final long serialVersionUID = -1340978779095092824L;

@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private String id;
private String firstName;
private String lastName;
private String address;
private String phoneNumber;
private String email;

}

The simple interface:

package com.alco.repository;

import org.springframework.data.jpa.repository.JpaRepository;

import com.alco.entity.Contact;

public interface ContactRepository extends JpaRepository<Contact, String> {

}
Neil Stockton
  • 11,383
  • 3
  • 34
  • 29
JKK
  • 436
  • 2
  • 11
  • 22
  • 2
    Is `com.alco.repository` as sub package of your app (main class with `@SpringBootApplication`? If not, it's not picking it up there. Maybe adding `@EnableJpaRepositories(basePackages = {"com.alco.repository"})` to your main app fixes the issue. – zapl May 28 '16 at 16:06

3 Answers3

7

I think you're missing enabling of the JPA repositories:

@ComponentScan(basePackageClasses = ...)
@EntityScan(basePackageClasses = ...)
@EnableAutoConfiguration
@EnableJpaRepositories(basePackageClasses = ...)
public class ... {
}

This would be for your configuration class.

0

The only thing I can see is this; please try with changing JpaRepository with Repository

import org.springframework.data.repository.Repository

public interface ContactRepository extends Repository<Contact, String> {
erolkaya84
  • 1,769
  • 21
  • 28
-1

You need to annotate your repository with @Repository, otherwise Spring will not manage your Repository class.

Do not use the more generic @Component, as it may lead to different behavior, e.g. in Exception Management. As an example, look at this parte of the Spring Documentation.

Excerpt:

The postprocessor automatically looks for all exception translators (implementations of the PersistenceExceptionTranslator interface) and advises all beans marked with the @Repository annotation so that the discovered translators can intercept and apply the appropriate translation on the thrown exceptions.

Also, as mentioned here, in the future you might have back-compatibility issues.

As an alternative, you can use @EnableJpaRepositories and specify where Spring should be looking for repositories.

Community
  • 1
  • 1
Manu
  • 4,019
  • 8
  • 50
  • 94
  • Shouldn't be necessary, there is no annotation in any of the examples ([CityRepository.java](https://github.com/spring-projects/spring-boot/blob/master/spring-boot-samples/spring-boot-sample-data-jpa/src/main/java/sample/data/jpa/service/CityRepository.java), [boot jpa getting started guide](https://spring.io/guides/gs/accessing-data-jpa/)). The generated code that magically implements these interfaces and that is autowired instead of the interface is properly annotated with `@Repository` and such. – zapl May 28 '16 at 16:11
  • This is not necessary for Spring Data JPA repository interfaces, only for Spring Beans (classes), which are used as part of a repository layer. – dunni May 28 '16 at 17:41
  • I think that either you use that annotation or put EnableJpaRepositories with appropriate attribute. Spring is telling you that it cannot find the interface, so help it. – Manu May 28 '16 at 17:59
  • This isn't necessary. The only thing needed is to enable the JPA repositories. – Joao Esperancinha May 28 '16 at 19:24