Не удается Autowire @Repository аннотированный интерфейс в Spring Boot


80

Я разрабатываю приложение для весенней загрузки, и здесь у меня возникла проблема. Я пытаюсь ввести аннотированный интерфейс @Repository, и, похоже, он вообще не работает. Я получаю эту ошибку

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

Вот мой код:

Основной класс приложения:

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

Класс сущности:

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;

}

Интерфейс репозитория:

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

}

Контроллер:

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

Я даже сравнил свой код с доступом к данным jpa , и у меня заканчиваются идеи, что не так с этим кодом. Любая помощь приветствуется. Заранее спасибо.

EDITED: я изменил свой код, как было предложено выше, и я не получаю эту ошибку, когда вставляю свой интерфейс @Repository в другой компонент. Однако сейчас у меня проблема - мой компонент не может быть получен (я использовал отладку). Что я делаю неправильно, поэтому Spring не может найти мой компонент?


А что, если вы создадите другой компонент и вставите в него свой UserEntityDao userEntityDao? (также замечание: никогда не вводите зависимости напрямую в поля, используйте конструктор с правильными аргументами и @ Autowired / @ Inject на нем).
Rafal G.

Ответы:


167

Если пакет репозитория отличается от @SpringBootApplication/ @EnableAutoConfiguration, @EnableJpaRepositoriesнеобходимо явно определить базовый пакет .

Попробуй добавить @EnableJpaRepositories("com.pharmacy.persistence.users.dao")в SpringBootRunner


4
Немного устарел, но добавление @EnableJpaRepositories в класс Application помогло.
Хатем Джабер,

4
В странной документации говорится: «По умолчанию Spring Boot включает поддержку репозитория JPA и просматривает пакет (и его подпакеты), где находится @SpringBootApplication». spring.io/guides/gs/accessing-data-jpa
magulla 03

4
@magulla: OP @SpringBootApplicationнаходятся в пакете com.pharmacy.config, а @EnableJpaRepositoriesнаходятся вcom.pharmacy.persistence.users.dao
hang321

28
У меня была такая же проблема. Как только я указал пакет для своих репозиториев, я получил еще одну ошибку Entity is not a managed type. Для всех, у кого есть эта проблема, вам также необходимо добавить аннотацию@EntityScan("com.package.dtos")
c.dunlap

2
Для MongoDB хранилищ добавить@EnableMongoRepositories("...")
Омид

41

У меня были те же проблемы с не найденным репозиторием. Я поместил все в один пакет. И это сработало, а это значит, что с моим кодом все в порядке. Я переместил Repos & Entities в другой пакет и добавил следующее в класс SpringApplication.

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

После этого я переместил Сервис (интерфейс и реализацию) в другой пакет и добавил следующее в класс SpringApplication.

@ComponentScan("com...service")

Это решило мои проблемы.


3
Это должен быть ответ, поскольку он полностью решает проблему. поскольку он выдает not mapped typeошибку после простого добавления@EnableJpaRepositories
Адитья Пешаве

24

Есть еще одна причина этого типа проблемы, о которой я хотел бы рассказать, потому что я борюсь с этой проблемой в течение некоторого времени и не могу найти никакого ответа на SO.

В репозитории вроде:

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

}

Если объект UserEntity не имеет@Entity аннотацию на классе, вы будете иметь ту же ошибку.

Эта ошибка сбивает с толку в этом случае, потому что вы сосредотачиваетесь на попытке решить проблему с Spring не нашел репозиторий, но проблема заключается в сущности. И если вы пришли к этому ответу, пытаясь протестировать свой репозиторий, этот ответ может вам помочь.


1
Взрыв! Работал! Спасибо.
Sparkyspider 04

2
Хороший крик! Благодарю. Для меня я использовал репозиторий Redis, поэтому определение красного хеша исправило его. например, @RedisHash (LanguageMapping.KEY_NAME)
theINtoy

16

Похоже, ваша @ComponentScanаннотация настроена неправильно. Пытаться :

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

На самом деле сканирование компонентов не требуется, если ваш основной класс находится наверху структуры, например, непосредственно под com.pharmacy пакетом.

Кроме того, вам не нужны оба

@SpringBootApplication
@EnableAutoConfiguration

@SpringBootApplicationАннотацию включает в себя @EnableAutoConfigurationпо умолчанию.


Собственно @ComponentScan("com.pharmacy")надо делать.
ci_

«На самом деле вам не нужно сканирование компонентов, если ваш основной класс находится наверху структуры» сработало для меня!
Адам

14

У меня была аналогичная проблема, когда я получал NoSuchBeanDefinitionExceptionв Spring Boot (в основном, когда работал над репозиторием CRUD), мне пришлось разместить следующие аннотации к основному классу:

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

Также убедитесь, что у вас есть @Componentаннотации к реализациям.


7

В SpringBoot JpaRepository по умолчанию не включается автоматически. Вы должны явно добавить

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

Та же проблема, с которой я столкнулся, у меня были Repo и Entity в проекте библиотеки, который был добавлен как зависимость в проект приложения. Там в App.java их нужно включить явно.
Фрэнсис Радж

3

Вот ошибка: как кто-то сказал раньше, вы используете org.pharmacy вместо com.pharmacy в 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

Чтобы расширить приведенные выше ответы, вы можете добавить более одного пакета в свой тег EnableJPARepositories, чтобы вы не столкнулись с ошибкой «Объект не сопоставлен» после того, как указали только пакет репозитория.

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

}

3

Вы сканируете не тот пакет:

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

Где как должно быть:

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

Поскольку имена ваших пакетов начинаются с com, а не с 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
Хотя этот код может решить вопрос, в том числе объяснение того, как и почему это решает проблему, действительно поможет улучшить качество вашего сообщения и, вероятно, приведет к большему количеству голосов за. Помните, что вы отвечаете на вопрос для будущих читателей, а не только для человека, который задает его сейчас. Пожалуйста , измените свой ответ , чтобы добавить объяснения и дать указание о том , что применять ограничения и допущения. Из отзыва
двойной гудок

2

У меня была аналогичная проблема с Spring Data MongoDB: мне пришлось добавить путь к пакету @EnableMongoRepositories


1

У меня была аналогичная проблема, но по другой причине:

В моем случае проблема заключалась в том, что в интерфейсе, определяющем репозиторий

public interface ItemRepository extends Repository {..}

Я опускал типы шаблона. Правильная установка:

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

сделали свое дело.


Потрясающе. Единственное решение, которое помогло мне исправить проблему;
Симран

1

У меня тоже были проблемы с этой темой. Вы должны убедиться, что вы определили пакеты в классе Spring boot runner, как в этом примере ниже:

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

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

Надеюсь, это поможет!


1

В @ComponentScan("org.pharmacy"), вы объявляете org.pharmacyпакет. Но ваши компоненты в com.pharmacyпакете.


1

Если вы столкнулись с этой проблемой при модульном тестировании с @DataJpaTest вы найдете решение ниже.

Spring boot не инициализирует @Repositorybeans для @DataJpaTest. Поэтому попробуйте одно из двух исправлений ниже, чтобы они были доступны:

Первый

@SpringBootTestВместо этого используйте . Но это загрузит весь контекст приложения.

Второй (лучшие решения)

Импортируйте нужный репозиторий, как показано ниже.

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

@Autowired
private MyRepository myRepository;

1

Это могло быть связано с пакетом, в котором он находится. У меня была аналогичная проблема:

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)

Действие:

Рассмотрите возможность определения компонента типа " repository.UserRepository" в вашей конфигурации. "

Решил это, поместив файлы репозитория в пакет со стандартизированным соглашением об именах:

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

и

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

Таким образом, Spring знает, где искать репозитории, иначе все очень быстро запутается. :)

Надеюсь это поможет.


0

Убедитесь, что @Serviceили, @Componentкоторый пытается автоматически подключить репозиторий, находится не в том же каталоге, что и ваш SpringApplication.class. Убедитесь, что он находится в подпапке вроде service/.


0

Иногда у меня возникали те же проблемы, когда я забывала добавить зависимость процессора аннотаций Lombok в конфигурацию maven

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.