web-dev-qa-db-fra.com

Impossible d'annoter l'interface annotée Autowire @Repository dans Spring Boot

Je développe une application de démarrage de printemps et je rencontre un problème ici. J'essaie d'injecter une interface annotée @Repository et cela ne semble pas fonctionner du tout. Je reçois cette erreur

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'springBootRunner': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.pharmacy.persistence.users.dao.UserEntityDao com.pharmacy.config.SpringBootRunner.userEntityDao; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.pharmacy.persistence.users.dao.UserEntityDao] 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)}
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.Java:334)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.Java:1202)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.Java:537)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.Java:476)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.Java:303)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.Java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.Java:299)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.Java:194)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.Java:755)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.Java:757)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.Java:480)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.Java:118)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.Java:686)
    at org.springframework.boot.SpringApplication.run(SpringApplication.Java:320)
    at org.springframework.boot.SpringApplication.run(SpringApplication.Java:957)
    at org.springframework.boot.SpringApplication.run(SpringApplication.Java:946)
    at com.pharmacy.config.SpringBootRunner.main(SpringBootRunner.Java:25)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.pharmacy.persistence.users.dao.UserEntityDao com.pharmacy.config.SpringBootRunner.userEntityDao; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.pharmacy.persistence.users.dao.UserEntityDao] 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)}
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.Java:561)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.Java:88)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.Java:331)
    ... 16 common frames omitted
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.pharmacy.persistence.users.dao.UserEntityDao] 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)}
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.Java:1301)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.Java:1047)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.Java:942)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.Java:533)
    ... 18 common frames omitted

Voici mon code:

Classe d'application principale:

package com.pharmacy.config;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;


@SpringBootApplication
@ComponentScan("org.pharmacy")
public class SpringBootRunner {


    public static void main(String[] args) {
        SpringApplication.run(SpringBootRunner.class, args);
    }
}

Classe d'entité:

package com.pharmacy.persistence.users;

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



@Entity
public class UserEntity {

    @Id
    @GeneratedValue
    private Long id;
    @Column
    private String name;

}

Interface de référentiel:

package com.pharmacy.persistence.users.dao;

import com.pharmacy.persistence.users.UserEntity;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;


@Repository
public interface UserEntityDao extends CrudRepository<UserEntity,Long>{

}

Manette:

package com.pharmacy.controllers;

import com.pharmacy.persistence.users.UserEntity;
import com.pharmacy.persistence.users.dao.UserEntityDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;


@RestController
public class HomeController {


    @Autowired
    UserEntityDao userEntityDao;

    @RequestMapping(value = "/")
    public String hello() {
        userEntityDao.save(new UserEntity("ac"));
        return "Test";

    }
}

build.gradle

buildscript {
    ext {
        springBootVersion = '1.2.2.RELEASE'
    }
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
    }
}

apply plugin: 'Java'
apply plugin: 'idea'
apply plugin: 'spring-boot'
mainClassName = "com.pharmacy.config.SpringBootRunner"
jar {
    baseName = 'demo'
    version = '0.0.1-SNAPSHOT'
}


repositories {
    mavenCentral()
}


dependencies {
    compile("org.springframework.boot:spring-boot-starter-data-jpa")
    compile("org.springframework.boot:spring-boot-starter-web")
    compile("org.springframework.boot:spring-boot-starter-ws")
    compile("postgresql:postgresql:9.0-801.jdbc4")

    testCompile("org.springframework.boot:spring-boot-starter-test")
}

application.properties:

spring.view.prefix: /
spring.view.suffix: .html

spring.jpa.database=POSTGRESQL
spring.jpa.show-sql=false
spring.jpa.hibernate.ddl-auto=update


spring.datasource.driverClassName=org.postgresql.Driver
spring.datasource.url=jdbc:postgresql://localhost:5432/postgres
spring.datasource.username=postgres
spring.datasource.password=abc123

J'ai même comparé mon code avec Accessing data jpa , et je manque d'idées sur ce qui ne va pas avec ce code. Toute aide appréciée. Merci d'avance.

EDITED: J'ai modifié mon code comme ci-dessus, et je ne reçois pas cette erreur lorsque j'injecte mon interface @Repository dans un autre composant. Cependant, j'ai un problème maintenant - mon composant ne peut pas être récupéré (j'ai utilisé le débogage). Qu'est-ce que je fais mal pour que le printemps ne trouve pas mon composant?

50
visst

Lorsque le package de référentiel est différent de @SpringBootApplication/@EnableAutoConfiguration, le package de base de @EnableJpaRepositories doit être défini explicitement.

Essayez d’ajouter @EnableJpaRepositories("com.pharmacy.persistence.users.dao") à SpringBootRunner.

118
hang321

J'ai eu les mêmes problèmes avec Repository non trouvé. Donc, ce que j'ai fait était de tout déplacer dans 1 paquet. Et cela a fonctionné signifiant qu'il n'y avait rien de mal avec mon code. J'ai déplacé les dépôts et les entités dans un autre package et ajouté les éléments suivants à la classe SpringApplication.

@EnableJpaRepositories("com...jpa")
@EntityScan("com...jpa")

Après cela, j'ai déplacé le service (interface et implémentation) vers un autre package et ajouté ce qui suit à la classe SpringApplication.

@ComponentScan("com...service")

Cela a résolu mes problèmes.

24
Sanjay Mistry

Ce que je voudrais dire, c’est une autre cause de ce type de problème, car j’ai du mal à le résoudre pendant un certain temps et je n’ai trouvé aucune réponse à ce sujet.

Dans un référentiel comme:

@Repository
public interface UserEntityDao extends CrudRepository<UserEntity, Long>{

}

Si votre entité UserEntity n'a pas l'annotation @Entity sur la classe, vous aurez la même erreur.

Cette erreur est source de confusion pour ce cas, car vous vous concentrez sur la résolution du problème de Spring qui n'a pas trouvé le référentiel, mais le problème, c'est l'entité. Et si vous êtes venu à cette réponse en essayant de tester votre référentiel, cette réponse peut vous aider.

14
Dherik

Il semble que votre annotation @ComponentScan ne soit pas définie correctement. Essayez:

@ComponentScan(basePackages = {"com.pharmacy"})

En fait, vous n'avez pas besoin de l'analyse du composant si votre classe principale figure en haut de la structure, par exemple directement sous le package com.pharmacy.

En outre, vous n'avez pas besoin des deux

@SpringBootApplication
@EnableAutoConfiguration

L'annotation @SpringBootApplication inclut @EnableAutoConfiguration par défaut.

12
Damien Polegato

J'avais un problème similaire où je recevais NoSuchBeanDefinitionException dans Spring Boot (essentiellement lorsque je travaillais sur le référentiel CRUD), je devais mettre les annotations ci-dessous sur la classe principale:

@SpringBootApplication   
@EnableAutoConfiguration
@ComponentScan(basePackages={"<base package name>"})
@EnableJpaRepositories(basePackages="<repository package name>")
@EnableTransactionManagement
@EntityScan(basePackages="<entity package name>")

Assurez-vous également que les annotations @Component sont en place sur les implémentations.

11
Vinayak Shenoy

Pour étendre les réponses ci-dessus, vous pouvez en réalité ajouter plusieurs packages dans votre balise EnableJPARepositories afin d'éviter de générer l'erreur "Objet non mappé" après avoir uniquement spécifié le package de référentiel.

@SpringBootApplication
@EnableJpaRepositories(basePackages = {"com.test.model", "com.test.repository"})
public class SpringBootApplication{

}
3
yogidilip

Voici l'erreur: comme vous l'avez déjà dit, vous utilisez org.pharmacy au lieu de com.pharmacy dans componentscan

    package **com**.pharmacy.config;

    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.context.annotation.ComponentScan;


    @SpringBootApplication
    @ComponentScan("**org**.pharmacy")
    public class SpringBootRunner {
2
Bence

J'ai eu quelques problèmes avec ce sujet aussi. Vous devez vous assurer de définir les packages dans la classe de runner de démarrage Spring comme dans l'exemple ci-dessous:

@SpringBootApplication
@EnableAutoConfiguration
@ComponentScan({"controller", "service"})
@EntityScan("entity")
@EnableJpaRepositories("repository")
public class Application {

    public static void main(String[] args){
        SpringApplication.run(Application.class, args);
    }

J'espère que ça aide!

1
dries vanbilloen

J'ai eu un problème similaire mais avec une cause différente:

Dans mon cas, le problème était que dans l'interface définissant le référentiel

public interface ItemRepository extends Repository {..}

J'omettais les types du modèle. Leur donner raison:

public interface ItemRepository extends Repository<Item,Long> {..}

a fait le tour.

1
Antoni

Vous analysez le mauvais paquet: @ComponentScan ("org. Pharmacy")

Où cela devrait être: @ComponentScan ("com. Pharmacy")

Puisque vos noms de paquets commencent par com et non org.

1
rahsan

Dans @ComponentScan("org.pharmacy"), vous déclarez org.pharmacy package. Mais vos composants dans le package com.pharmacy.

0
yuen26

Si vous rencontrez ce problème lors des tests unitaires avec @DataJpaTest, alors vous trouverez la solution ci-dessous.

L'initialisation de printemps n'initialise pas les beans @Repository pour @DataJpaTest. Essayez donc l’un des deux correctifs ci-dessous pour les mettre à disposition:

Premier

Utilisez @SpringBootTest à la place. Mais cela démarrera tout le contexte de l'application.

Deuxième (Meilleures solutions)

Importez le référentiel spécifique dont vous avez besoin, comme ci-dessous

@DataJpaTest
@Import(MyRepository.class)
public class MyRepositoryTest {

@Autowired
private MyRepository myRepository;
0
Meena Chaudhary

Dans SpringBoot, les réactifs JpaRepository ne sont pas activés automatiquement par défaut. Vous devez ajouter explicitement

@EnableJpaRepositories("packages")
@EntityScan("packages")
0
priyank