No se puede conectar automáticamente la interfaz anotada de @Repository en Spring Boot


80

Estoy desarrollando una aplicación de arranque de primavera y tengo un problema aquí. Estoy tratando de inyectar una interfaz anotada @Repository y no parece funcionar en absoluto. Estoy recibiendo este error

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

Aquí está mi código:

Clase de aplicación principal:

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);
    }
}

Clase de entidad:

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;

}

Interfaz del repositorio:

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>{

}

Controlador:

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

Incluso comparé mi código con Accessing data jpa , y me estoy quedando sin ideas sobre lo que está mal con este código. Cualquier ayuda apreciada. Gracias por adelantado.

EDITADO: Cambié mi código como se sugirió para que se vea como arriba, y no obtengo ese error cuando estoy inyectando mi interfaz @Repository en otro componente. Sin embargo, ahora tengo un problema: mi componente no se puede recuperar (utilicé la depuración). ¿Qué estoy haciendo mal para que Spring no pueda encontrar mi componente?


¿Y si crea otro componente y le inyecta su 'UserEntityDao userEntityDao'? (también una nota al margen: nunca inyecte dependencias directamente a los campos, use el constructor con los argumentos adecuados y @ Autowired / @ Inject en él).
Rafal G.

Respuestas:


167

Cuando el paquete del repositorio es diferente a @SpringBootApplication/ @EnableAutoConfiguration, @EnableJpaRepositorieses necesario definir explícitamente el paquete base de .

Intente agregar @EnableJpaRepositories("com.pharmacy.persistence.users.dao")a SpringBootRunner


4
Un poco viejo, pero agregar @EnableJpaRepositories en la clase Application funcionó.
Hatem Jaber

4
Los documentos extraños dicen "De forma predeterminada, Spring Boot habilitará el soporte del repositorio JPA y buscará en el paquete (y sus subpaquetes) donde se encuentra @SpringBootApplication". spring.io/guides/gs/accessing-data-jpa
magulla

4
@magulla: OP se @SpringBootApplicationencuentra en el paquete com.pharmacy.config, mientras que se @EnableJpaRepositoriesencuentra encom.pharmacy.persistence.users.dao
hang321

28
Tuve el mismo problema. Una vez que especifiqué un paquete para mis repositorios, recibí otro error Entity is not a managed type. Para cualquier otra persona que tenga este problema, también debe agregar la anotación@EntityScan("com.package.dtos")
c.dunlap

2
Para repositorios de MongoDB, agregue@EnableMongoRepositories("...")
Omid

41

Tuve los mismos problemas con el repositorio no encontrado. Entonces, lo que hice fue mover todo en un solo paquete. Y esto funcionó, lo que significa que no había nada malo con mi código. Moví Repos & Entities a otro paquete y agregué lo siguiente a la clase SpringApplication.

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

Después de eso, moví el Servicio (interfaz e implementación) a otro paquete y agregué lo siguiente a la clase SpringApplication.

@ComponentScan("com...service")

Esto resolvió mis problemas.


3
Esta debería ser la respuesta en realidad, ya que resolvió el problema completo. ya que da not mapped typeerror después de simplemente agregar@EnableJpaRepositories
Aditya Peshave

24

Hay otra causa para este tipo de problema que me gustaría compartir, porque lucho con este problema durante algún tiempo y no pude encontrar ninguna respuesta en SO.

En un repositorio como:

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

}

Si su entidad UserEntity no tiene la @Entityanotación en la clase, tendrá el mismo error.

Este error es confuso para este caso, porque te enfocas en intentar resolver el problema de que Spring no encontró el Repositorio pero el problema es la entidad. Y si llegó a esta respuesta tratando de probar su Repositorio, esta respuesta puede ayudarlo.


1
¡Explosión! ¡Trabajó! Gracias.
Sparkyspider

2
Buen grito! Gracias. Para mí, estaba usando un repositorio de redis, por lo que definir el hash rojizo lo solucionó. Por ejemplo, @RedisHash (LanguageMapping.KEY_NAME)
theINtoy

16

Parece que su @ComponentScananotación no está configurada correctamente. Tratar :

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

En realidad, no necesita el análisis de componentes si tiene su clase principal en la parte superior de la estructura, por ejemplo, directamente debajo del com.pharmacypaquete.

Además, no necesitas ambos

@SpringBootApplication
@EnableAutoConfiguration

La @SpringBootApplicationanotación incluye @EnableAutoConfigurationde forma predeterminada.


En realidad @ComponentScan("com.pharmacy")debería hacer.
ci_

"En realidad, no necesita el escaneo de componentes si tiene su clase principal en la parte superior de la estructura" ¡funcionó para mí!
Adam

14

Tuve un problema similar en el que recibía NoSuchBeanDefinitionExceptionen Spring Boot (básicamente mientras trabajaba en el repositorio CRUD), tuve que poner las siguientes anotaciones en la clase principal:

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

Además, asegúrese de tener las @Componentanotaciones en su lugar en las implementaciones.


7

En SpringBoot, JpaRepository no se habilita automáticamente de forma predeterminada. Tienes que agregar explícitamente

@EnableJpaRepositories("packages")
@EntityScan("packages")

El mismo problema al que me enfrentaba, tenía Repo y Entity en un proyecto de biblioteca, que se agregó como una dependencia en un proyecto de aplicación. Allí en la App.java es necesario habilitarlos explícitamente.
Francis Raj

3

Aquí está el error: como alguien dijo antes, está utilizando org.pharmacy en lugar de com.pharmacy en 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 {

3

Para ampliar las respuestas anteriores, puede agregar más de un paquete en su etiqueta EnableJPARepositories, para que no se encuentre con el error "Objeto no asignado" después de especificar el paquete del repositorio.

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

}

3

Está escaneando el paquete incorrecto:

@ComponentScan("**org**.pharmacy")

Donde como debería estar:

@ComponentScan("**com**.pharmacy")

Dado que los nombres de sus paquetes comienzan con com y no org.


3
@SpringBootApplication(scanBasePackages=,<youur package name>)
@EnableJpaRepositories(<you jpa repo package>)
@EntityScan(<your entity package>)

Entity class like below 
@Entity
@Table(name="USER")
public class User {

    @Id
    @GeneratedValue

2
Si bien este código puede resolver la pregunta, incluir una explicación de cómo y por qué esto resuelve el problema realmente ayudaría a mejorar la calidad de su publicación y probablemente resultaría en más votos a favor. Recuerde que está respondiendo la pregunta a los lectores en el futuro, no solo a la persona que pregunta ahora. Por favor, editar su respuesta para agregar explicaciones y dar una indicación de lo que se aplican limitaciones y supuestos. De la opinión
doble pitido

2

Tuve un problema similar con Spring Data MongoDB: tuve que agregar la ruta del paquete a @EnableMongoRepositories


1

Tuve un problema similar pero con una causa diferente:

En mi caso el problema fue que en la interfaz que define el repositorio

public interface ItemRepository extends Repository {..}

Estaba omitiendo los tipos de plantilla. Poniéndolos bien:

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

Hizo el truco.


Increíble. La única solución que me ayudó a solucionar el problema;
Simran kaur

1

También tuve algunos problemas con este tema. Debe asegurarse de definir los paquetes en la clase Spring boot runner como este ejemplo a continuación:

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

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

¡Espero que esto ayude!


1

En @ComponentScan("org.pharmacy"), está declarando org.pharmacypackage. Pero sus componentes en el com.pharmacypaquete.


1

Si se enfrenta a este problema al realizar pruebas unitarias con @DataJpaTest, encontrará la solución a continuación.

Spring boot no inicializa @Repositorybeans para @DataJpaTest. Así que pruebe una de las dos soluciones siguientes para tenerlas disponibles:

primero

Úselo en su @SpringBootTestlugar. Pero esto iniciará todo el contexto de la aplicación.

Segundo (mejores soluciones)

Importe el repositorio específico que necesita, como a continuación

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

@Autowired
private MyRepository myRepository;

1

Podría tener que ver con el paquete en el que lo tienes. Tuve un problema similar:

Description:
Field userRepo in com.App.AppApplication required a bean of type 'repository.UserRepository' that could not be found.

The injection point has the following annotations:
    - @org.springframework.beans.factory.annotation.Autowired(required=true)

Acción:

Considere definir un bean de tipo ' repository.UserRepository' en su configuración. "

Lo resolvió colocando los archivos del repositorio en un paquete con una convención de nomenclatura estandarizada:

e.g. com.app.Todo (for main domain files)

y

com.app.Todo.repository (for repository files)

De esa manera, Spring sabe dónde buscar los repositorios, de lo contrario, las cosas se vuelven confusas muy rápido. :)

Espero que esto ayude.


0

Asegúrese de que @Serviceo @Componentque está intentando conectar automáticamente el repositorio no esté en el mismo directorio que su SpringApplication.class. Asegúrese de que esté en una subcarpeta como service/.


0

A veces tuve los mismos problemas cuando me olvido de agregar la dependencia del procesador de anotaciones de Lombok a la configuración de maven

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.