Не вдається автоматично підключити @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

Я навіть порівняв свій код з Accessing data jpa , і у мене закінчуються ідеї, що з цим кодом не так. Будь-яка допомога оцінена. Заздалегідь спасибі.

ВИДАЛЕНО: Я змінив свій код, як пропонувалось виглядати вище, і я не отримую цієї помилки, коли ввожу свій інтерфейс @Repository в інший компонент. Однак у мене зараз проблема - не вдається отримати мій компонент (я використовував налагодження). Що я роблю неправильно, щоб весна не могла знайти свій компонент?


А що, якщо ви створите інший компонент і введете в нього свій 'UserEntityDao userEntityDao'? (також sidenote: ніколи не вводьте залежності безпосередньо в поля, використовуйте конструктор із належними аргументами та @ Autowired / @ Inject).
Рафал Г.

Відповіді:


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

4
@magulla: ОП @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

У мене були ті самі проблеми, що сховище не було знайдено. Отже, що я зробив, це перемістив все в 1 пакет. І це спрацювало, що означає, що в моєму коді не було нічого поганого. Я перемістив 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

2
Гарний крик! Дякую. Для мене я використовував репо-редис, тому визначення червонуватого хешу це зафіксувало. напр. @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 у компонентах

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

зробив фокус.


Приголомшливо Єдине рішення, яке допомогло мені вирішити проблему;
Simran kaur,

1

У мене теж були проблеми з цією темою. Ви повинні переконатися, що визначили пакети в класі завантажувача Spring, як у цьому прикладі нижче:

@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 завантаження не ініціалізує @Repositoryкомпоненти для @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)

Таким чином, весна знає, куди йти шукати сховища, інакше речі дуже швидко заплутаються. :)

Сподіваюся, це допомагає.


0

Переконайтеся, що @Serviceабо @Componentте, що намагається автоматично зв’язати сховище, не знаходиться в тому ж каталозі, що і ваш SpringApplication.class. Переконайтеся, що він знаходиться у підпапці типу service/.


0

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.