Die mit @Repository kommentierte Schnittstelle kann im Spring Boot nicht automatisch verdrahtet werden

79

Ich entwickle eine Spring-Boot-Anwendung und stoße hier auf ein Problem. Ich versuche, eine mit @Repository kommentierte Schnittstelle einzufügen, und es scheint überhaupt nicht zu funktionieren. Ich erhalte diesen Fehler

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

Hier ist mein Code:

Hauptanwendungsklasse:

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

Entitätsklasse:

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;

}

Repository-Schnittstelle:

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

}

Regler:

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

Ich habe meinen Code sogar mit dem Zugriff auf Daten jpa verglichen , und mir gehen die Ideen aus, was mit diesem Code nicht stimmt. Jede Hilfe geschätzt. Danke im Voraus.

BEARBEITET: Ich habe meinen Code wie oben vorgeschlagen geändert und sehe diesen Fehler nicht, wenn ich meine @ Repository-Schnittstelle in eine andere Komponente einfüge. Jetzt habe ich jedoch ein Problem - meine Komponente kann nicht abgerufen werden (ich habe das Debuggen verwendet). Was mache ich falsch, damit der Frühling meine Komponente nicht finden kann?

visst
quelle
Und was ist, wenn Sie eine andere Komponente erstellen und ihr 'UserEntityDao userEntityDao' hinzufügen? (auch eine Nebenbemerkung: Fügen Sie niemals Abhängigkeiten direkt in Felder ein, verwenden Sie den Konstruktor mit den richtigen Argumenten und @ Autowired / @ Inject darauf).
Rafal G.

Antworten:

166

Wenn sich das Repository-Paket von @SpringBootApplication/ unterscheidet @EnableAutoConfiguration, muss das Basispaket von @EnableJpaRepositoriesexplizit definiert werden.

Versuchen Sie @EnableJpaRepositories("com.pharmacy.persistence.users.dao"), SpringBootRunner hinzuzufügen

hang321
quelle
4
Ein bisschen alt, aber das Hinzufügen von @EnableJpaRepositories zur Application-Klasse hat den Trick getan.
Hatem Jaber
4
In seltsamen Dokumenten heißt es: "Standardmäßig aktiviert Spring Boot die JPA-Repository-Unterstützung und sucht in dem Paket (und seinen Unterpaketen), in dem sich @SpringBootApplication befindet." spring.io/guides/gs/accessing-data-jpa
magulla
4
@magulla: OPs befinden @SpringBootApplicationsich im Paket com.pharmacy.config, während sie @EnableJpaRepositoriessich incom.pharmacy.persistence.users.dao
hang321
28
Ich hatte das gleiche Problem. Nachdem ich ein Paket für meine Repositorys angegeben hatte, wurde ein weiterer Fehler angezeigt Entity is not a managed type. Für alle anderen, die dieses Problem haben, müssen Sie auch die Anmerkung hinzufügen@EntityScan("com.package.dtos")
c.dunlap
2
Für MongoDB-Repositorys hinzufügen@EnableMongoRepositories("...")
Omid
39

Ich hatte die gleichen Probleme mit Repository nicht gefunden. Also habe ich alles in ein Paket verschoben. Und das hat funktioniert, was bedeutet, dass an meinem Code nichts falsch war. Ich habe die Repos & Entities in ein anderes Paket verschoben und der SpringApplication-Klasse Folgendes hinzugefügt.

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

Danach habe ich den Service (Schnittstelle & Implementierung) in ein anderes Paket verschoben und der SpringApplication-Klasse Folgendes hinzugefügt.

@ComponentScan("com...service")

Dies löste meine Probleme.

Sanjay Mistry
quelle
3
Dies sollte die eigentliche Antwort sein, da das gesamte Problem behoben wurde. wie es not mapped typeFehler gibt , nachdem nur hinzugefügt@EnableJpaRepositories
Aditya Peshave
24

Es gibt eine andere Ursache für diese Art von Problem, die ich gerne teilen möchte, da ich einige Zeit mit diesem Problem zu kämpfen habe und auf SO keine Antwort finden konnte.

In einem Repository wie:

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

}

Wenn Ihre Entität UserEntity nicht über die @EntityAnnotation für die Klasse verfügt, wird derselbe Fehler angezeigt.

Dieser Fehler ist in diesem Fall verwirrend, da Sie sich darauf konzentrieren, das Problem zu beheben, dass Spring das Repository nicht gefunden hat, das Problem jedoch die Entität ist. Wenn Sie zu dieser Antwort gekommen sind und versucht haben, Ihr Repository zu testen, kann diese Antwort Ihnen helfen.

Dherik
quelle
1
Knall! Hat funktioniert! Vielen Dank.
Sparkyspider
2
Guter Ruf! Vielen Dank. Für mich habe ich ein Redis-Repo verwendet, also hat die Definition des rötlichen Hashs das Problem behoben. zB @RedisHash (LanguageMapping.KEY_NAME)
theINtoy
16

Es scheint, dass Ihre @ComponentScanAnmerkung nicht richtig eingestellt ist. Versuchen :

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

Eigentlich brauchen Sie den Komponentenscan nicht, wenn Sie Ihre Hauptklasse oben in der Struktur haben, zum Beispiel direkt unter com.pharmacyPaket.

Außerdem brauchen Sie nicht beides

@SpringBootApplication
@EnableAutoConfiguration

Die @SpringBootApplicationAnmerkung enthält @EnableAutoConfigurationstandardmäßig.

Damien Polegato
quelle
Sollte @ComponentScan("com.pharmacy")eigentlich reichen.
ci_
"Eigentlich brauchen Sie den Komponentenscan nicht, wenn Sie Ihre Hauptklasse oben in der Struktur haben" hat bei mir funktioniert!
Adam
13

Ich hatte ein ähnliches Problem, bei dem ich NoSuchBeanDefinitionExceptionin Spring Boot empfangen wurde (im Grunde genommen während der Arbeit am CRUD-Repository). Ich musste die folgenden Anmerkungen in die Hauptklasse einfügen:

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

Stellen Sie außerdem sicher, dass die @ComponentAnmerkungen zu den Implementierungen vorhanden sind.

Vinayak Shenoy
quelle
7

In SpringBoot werden die JpaRepository standardmäßig nicht automatisch aktiviert. Sie müssen explizit hinzufügen

@EnableJpaRepositories("packages")
@EntityScan("packages")
Priyank
quelle
Das gleiche Problem, mit dem ich konfrontiert war, war Repo und Entity in einem Bibliotheksprojekt, das als Abhängigkeit in einem Anwendungsprojekt hinzugefügt wurde. Dort in der App.java müssen diese explizit aktiviert werden.
Francis Raj
3

Hier ist der Fehler: Wie bereits erwähnt, verwenden Sie org.pharmacy insted von com.pharmacy in 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 {
Bence
quelle
3

Um auf die obigen Antworten einzugehen, können Sie Ihrem EnableJPARepositories-Tag tatsächlich mehr als ein Paket hinzufügen, sodass Sie nicht auf den Fehler "Objekt nicht zugeordnet" stoßen, nachdem Sie nur das Repository-Paket angegeben haben.

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

}
Yogidilip
quelle
3

Sie scannen das falsche Paket:

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

Wo wie es sein sollte:

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

Da Ihre Paketnamen mit com und nicht org beginnen.

rahsan
quelle
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
user2638041
quelle
2
Während dieser Code die Frage lösen kann, einschließlich einer Erklärung, wie und warum dies das Problem löst, würde dies wirklich dazu beitragen, die Qualität Ihres Beitrags zu verbessern, und wahrscheinlich zu mehr Up-Votes führen. Denken Sie daran, dass Sie in Zukunft die Frage für die Leser beantworten, nicht nur für die Person, die jetzt fragt. Bitte bearbeiten Sie Ihre Antwort, um Erklärungen hinzuzufügen und anzugeben, welche Einschränkungen und Annahmen gelten. Aus der Überprüfung
Doppel-Piepton
1

Ich hatte ein ähnliches Problem, aber mit einer anderen Ursache:

In meinem Fall bestand das Problem darin, dass in der Schnittstelle das Repository definiert wurde

public interface ItemRepository extends Repository {..}

Ich habe die Typen der Vorlage weggelassen. Richtig einstellen:

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

hat den Trick gemacht.

Antoni
quelle
Genial. Einzige Lösung, die mir geholfen hat, das Problem zu beheben.
Simran Kaur
1

Ich hatte auch einige Probleme mit diesem Thema. Sie müssen sicherstellen, dass Sie die Pakete in der Spring Boot Runner-Klasse wie im folgenden Beispiel definieren:

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

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

Ich hoffe das hilft!

trocknet vanbilloen
quelle
1

In @ComponentScan("org.pharmacy")deklarieren Sie das org.pharmacyPaket. Aber Ihre Komponenten im com.pharmacyPaket.

yuen26
quelle
1

Wenn Sie beim Unit-Test mit diesem Problem konfrontiert sind, @DataJpaTestfinden Sie unten die Lösung.

Spring Boot initialisiert keine @RepositoryBeans für @DataJpaTest. Versuchen Sie also eine der beiden folgenden Lösungen, um sie verfügbar zu machen:

Zuerst

Verwenden Sie @SpringBootTeststattdessen. Dadurch wird jedoch der gesamte Anwendungskontext gestartet.

Zweitens (bessere Lösungen)

Importieren Sie das gewünschte Repository wie unten beschrieben

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

@Autowired
private MyRepository myRepository;
Meena Chaudhary
quelle
1

Es könnte mit dem Paket zu tun haben, in dem Sie es haben. Ich hatte ein ähnliches Problem:

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)

Aktion:

Erwägen Sie repository.UserRepository, in Ihrer Konfiguration eine Bean vom Typ ' ' zu definieren . ""

Es wurde behoben, indem die Repository-Dateien in einem Paket mit standardisierter Namenskonvention abgelegt wurden:

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

und

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

Auf diese Weise weiß Spring, wo er nach den Repositories suchen muss, sonst werden die Dinge sehr schnell verwirrend. :) :)

Hoffe das hilft.

Zach
quelle
1

Ich hatte ein ähnliches Problem mit Spring Data MongoDB: Ich musste den Paketpfad hinzufügen @EnableMongoRepositories

mdeazley
quelle
0

Stellen Sie sicher, dass sich das @Serviceoder @Componentdas versucht, das Repository automatisch zu verkabeln, nicht im selben Verzeichnis wie Ihr befindet SpringApplication.class. Stellen Sie sicher, dass es sich in einem Unterordner wie befindet service/.

Sparkyspider
quelle
0

Manchmal hatte ich die gleichen Probleme, als ich vergaß, der Maven-Konfiguration die Abhängigkeit des Lombok-Annotationsprozessors hinzuzufügen

Oleg Ushakov
quelle