«Поле требует bean типа, который не может быть найден». ошибка Spring restful API с использованием mongodb


101

Итак, я изучаю Spring пару недель, следуя этому руководству

Создание веб-службы RESTful

Все было хорошо, пока я не попытался интегрировать его в mongodb. Итак, я следую этому руководству.

Доступ к данным с помощью MongoDB

Но моя практика частично все еще использует первый. Итак, моя структура каталогов проекта такая.

src/
├── main/
│   └── java/
|       ├── model/
|       |   └── User.java
|       ├── rest/
|       |   ├── Application.java
|       |   ├── IndexController.java
|       |   └── UsersController.java
|       └── service/
|           └── UserService.java
└── resources/
    └── application.properties

Это моя модель / файл User.java

package main.java.model;

import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;

@Document(collection="user")
public class User {

    private int age;
    private String country; 
    @Id
    private String id;
    private String name;


    public User() {
        super();
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getCountry() {
        return country;
    }

    public void setCountry(String country) {
        this.country = country;
    }
}

Это мой файл rest / UsersController.java

package main.java.rest;

import java.util.List;
import main.java.service.UserService;
import main.java.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping(value = "/users")
public class UsersController {

    @Autowired
    UserService userService;

    @RequestMapping(method = RequestMethod.GET)
    public List<User> getAllUsers() {
        return userService.findAll();
    }
}

Это мой файл service / UserService.java

package main.java.service;

import java.util.List;
import main.java.model.User;
import org.springframework.data.mongodb.repository.MongoRepository;

public interface UserService extends MongoRepository<User, String> {
    public List<User> findAll();
}

Я мог бы их скомпилировать (я использую gradle для компиляции, потому что следую руководству), но когда я запускал файл jar, он выдавал эту ошибку.


ПРИЛОЖЕНИЕ НЕ ЗАПУСКАЕТСЯ


Описание:

Поле userService в main.java.rest.UsersController требовало bean-компонента типа main.java.service.UserService, который не удалось найти.

Действие:

Рассмотрите возможность определения bean-компонента типа main.java.service.UserService в вашей конфигурации.

Не уверен, что не так, я начал гуглить и обнаружил, что мне нужно включить Beans.xmlфайл и зарегистрировать в нем userService. Я сделал это, но это не работает. Я новичок в этом, поэтому понятия не имею, что происходит.

Ответы:


160

Решил это. Таким образом, по умолчанию все пакеты, подпадающие под @SpringBootApplicationдекларацию, будут проверены.

Предполагая, что мой основной класс, ExampleApplicationкоторый имеет @SpringBootApplicationобъявление, объявлен внутри com.example.something, тогда все компоненты, которые подпадают под com.example.somethingэто, сканируются, в то время как com.example.applicantне будут сканироваться.

Итак, есть два способа сделать это, основываясь на этом вопросе . Использовать

@SpringBootApplication(scanBasePackages={
"com.example.something", "com.example.application"})

Таким образом, приложение просканирует все указанные компоненты, но я думаю, что, если бы масштаб увеличивался?

Итак, я использую второй подход, реструктурируя свои пакеты, и он сработал! Теперь структура моих пакетов стала такой.

src/
├── main/
│   └── java/
|       ├── com.example/
|       |   └── Application.java
|       ├── com.example.model/
|       |   └── User.java
|       ├── com.example.controller/
|       |   ├── IndexController.java
|       |   └── UsersController.java
|       └── com.example.service/
|           └── UserService.java
└── resources/
    └── application.properties

на самом деле ничего особенного не изменилось, я просто переименовал пакеты и классы @GuoJing
Eka Rudianto 02

@ekaRudianto Опечатка. Нет открытия {дляscanBasePackages= "com.example.something","com.example.application"
brk

У меня также была такая же проблема, и я понял, что моя структура пакета не в правильном порядке. Я их вот так переставил, и теперь все работает нормально.
Вимукти


20

У меня тоже была такая же ошибка:

***************************
APPLICATION FAILED TO START
***************************

Description:

Field repository in com.kalsym.next.gen.campaign.controller.CampaignController required a bean of type 'com.kalsym.next.gen.campaign.data.CustomerRepository' that could not be found.


Action:

Consider defining a bean of type 'com.kalsym.next.gen.campaign.data.CustomerRepository' in your configuration.de here

И мои пакеты были построены так же, как указано в принятом ответе. Я исправил свою проблему, добавив аннотацию EnableMongoRepositories в основной класс следующим образом:

@SpringBootApplication
@EnableMongoRepositories(basePackageClasses = CustomerRepository.class)
public class CampaignAPI {

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

Если вам нужно добавить несколько, не забудьте фигурные скобки:

@EnableMongoRepositories(basePackageClasses
    = {
        MSASMSRepository.class, APartyMappingRepository.class
    })

14

Я столкнулся с той же проблемой, и все, что мне нужно было сделать, это поместить приложение в пакет на один уровень выше, чем пакеты услуг, dao и домена.


12

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

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


10

Потратил много времени из-за автоимпорта. Intellij Идея почему-то импортирована @Serviceиз import org.jvnet.hk2.annotations.Service;вместо import org.springframework.stereotype.Service;!


Не могли бы вы обновить свой ответ и объяснить, что вы делаете. Большое спасибо заранее
MZaragoza

3
Что вы не поняли из моего ответа? У меня та же ошибка, что и в вопросе, при попытке запустить проект. Это потому, что я импортировал Serviceиз неправильной библиотеки.
Виталий Кузьмин

@VitaliKuzmin по-прежнему нет ясности в вашем ответе. Ваш ответ может быть правильным, и он, возможно, сработал для вас, но то, как вы представили здесь, сбивает с толку и не
подходит для

3
@mannedear Я думаю, что мой первый комментарий также отвечает на ваш комментарий.
Виталий Кузьмин

+1 к этому ответу, так как я тоже сделал ошибку импорта! : 0 import javax.persistence.Table;вместо import org.springframework.data.relational.core.mapping.Table;моей модели. smh потерял 5 часов на отладку этой ошибки bean-компонента.
калпадж агравалла



5

Обычно мы можем решить эту проблему двумя способами:

  1. правильная аннотация должна использоваться для Spring Boot, сканирующего bean-компонент , например @Component;
  2. сканирования путь будет включать в себя классы так же , как все остальные упомянутые выше.

Кстати, есть очень хорошее объяснение разницы между @Component, @Repository, @Service и @Controller .


3

Добавьте @Repository в свой класс dao

пример:

@Repository
public class DaoClassName implements IIntefaceDao {
}

2

Использование всех аннотаций @ устранило мою проблему. (Да, я новичок в Spring). Если вы используете класс обслуживания, добавьте @Service, то же самое для @Controller и @Repository.

Затем эти аннотации в App.java устранили проблему (я использую JPA + Hibernate)

@SpringBootApplication
@EnableAutoConfiguration(exclude = { ErrorMvcAutoConfiguration.class })
@ComponentScan(basePackages = {"es.unileon.inso2"})
@EntityScan("es.unileon.inso2.model")
@EnableJpaRepositories("es.unileon.inso2.repository")

Дерево пакетов:

src/
├── main/
│   └── java/
|       ├── es.unileon.inso2/
|       |   └── App.java
|       ├── es.unileon.inso2.model/
|       |   └── User.java
|       ├── es.unileon.inso2.controller/
|       |   ├── IndexController.java
|       |   └── UserController.java
|       ├── es.unileon.inso2.service/
|       |    └── UserService.java
|       └── es.unileon.inso2.repository/
|            └── UserRepository.java
└── resources/
    └── application.properties

2

У меня такая же проблема, исправленная путем добавления @EnableMongoRepositories ("in.topthree.util")

package in.topthree.core;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;

import in.topthree.util.Student;

@SpringBootApplication
@EnableMongoRepositories("in.topthree.util")
public class Run implements CommandLineRunner {

    public static void main(String[] args) {
        SpringApplication.run(Run.class, args);
        System.out.println("Run");
    }

    @Autowired
    private Process pr;

    @Override
    public void run(String... args) throws Exception {
        pr.saveDB(new Student("Testing", "FB"));
        System.exit(0);
    }

}

И мой репозиторий:

package in.topthree.util;

import org.springframework.data.mongodb.repository.MongoRepository;

public interface StudentMongo extends MongoRepository<Student, Integer> {

    public Student findByUrl(String url);
}

Теперь его работа


1

Мои классы реализации Mapper в моей целевой папке были удалены, поэтому у моих интерфейсов Mapper больше не было классов реализации. Таким образом, я получил ту же ошибкуField *** required a bean of type ***Mapper that could not be found.

Мне просто пришлось регенерировать мои реализации картографов с помощью maven и обновить проект ...


1

Я пришел к этому сообщению в поисках помощи при использовании Spring Webflux с Mongo Repository.

Моя ошибка была похожа на ошибку владельца

Field usersRepository in foobar.UsersService required
a bean of type 'foobar.UsersRepository' that could not be found.

Поскольку я раньше работал с Spring MVC, я был удивлен этой ошибкой.

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

Во-первых, вы должны помнить о том, что было упомянуто в ответе, отмеченном как принятый - иерархия пакетов.

Вторая важная вещь заключается в том, что если вы используете Webflux, вам нужно использовать какой-то другой пакет, а при использовании Spring MVC, например, для MongoDB, вам нужно добавить

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-mongodb-reactive</artifactId>
</dependency>

с -reactive в конце.


1

Я была такая же проблема. Моя ошибка заключалась в том, что я использовал аннотацию @Service в интерфейсе службы. Аннотацию @Service следует применить к классу ServiceImpl.


1

Добавьте @Repository в свой класс dao

    @Repository
    public interface UserDao extends CrudRepository<User, Long> {
         User findByUsername(String username);
         User findByEmail(String email);    
      }

нет необходимости добавлять @Repository, если вы уже расширяете CrudRepository
Карен Гох

1

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


1

вам нужно импортировать spring-boot-starter-data-jpa в качестве зависимости, если вы используете весеннюю загрузку


0

Это может произойти, когда два боба имеют одинаковые имена.

Module1Beans.java

@Configuration
public class Module1Beans {
    @Bean
    public GoogleAPI retrofitService(){
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("https://www.google.com/")
                .addConverterFactory(JacksonConverterFactory.create())
                .build();
        return retrofit.create(GoogleAPI.class);
    }
}

Module2Beans.java

@Configuration
public class Module2Beans {
    @Bean
    public GithubAPI retrofitService(){
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("https://www.github.com/")
                .addConverterFactory(JacksonConverterFactory.create())
                .build();
        return retrofit.create(GithubAPI.class);
    }
}

retrofitServiceСначала создается bean-компонент с именем и его типом GoogleAPI, а затем он покрывается, GithubAPIпотому что они оба созданы retrofitService()методом. Теперь , когда вы вы получите такое сообщение@AutowiredGoogleAPIField googleAPI in com.example.GoogleService required a bean of type 'com.example.rest.GoogleAPI' that could not be found.


0

В моем случае я просто поместил класс MyprojectApplication в пакет (com.example.start) с таким же уровнем модели, контроллера и пакетов услуг.


0

Я знаю, что он старый, но хочу добавить свои 5 центов.

Я использовал .serviceи .service.implв структуре папок, чтобы отделить сервис от его реализации. Забудьте реализовать часть ServiceImplementation.


0

Чтобы создать bean-компонент и внедрить его, класс должен быть помечен @ Componet, @ service, @ Repository и т. Д. В соответствии с контекстом вашего контекста, он должен быть

package main.java.service;

import java.util.List;
import main.java.model.User;
import org.springframework.data.mongodb.repository.MongoRepository;
@Repository
public interface UserService extends MongoRepository<User, String> {
    public List<User> findAll();
}

0

Для меня это сообщение:

org.apache.wicket.WicketRuntimeException: Can't instantiate page using constructor 'public org.package.MyClass(org.apache.wicket.request.mapper.parameter.PageParameters)' and argument ''. Might be it doesn't exist, may be it is not visible (public).

означало "в моем модульном тесте калитки вверху вы должны вручную добавить этот bean-компонент как"

appContext.putBean(myClass);

0

Я выполнил все шаги и инструкции, за которыми следовал OP здесь, позаботился о пустом пространстве вокруг имени пользователя и пароля (хотя spring заботится о пробелах в файле свойств), все еще сталкивался с

could not find bean for ___Repository

(у вас интерфейс, который расширяет JPARepository)

ИЛИ после добавления @EnableJPARepository

could not find bean for EntityManagerFactory

Я решил это, изменив родительскую версию Spring Boot Starter с 2.3.2 на 2.2.1 в pom.xml

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.2.1.RELEASE</version>
    <relativePath /> <!-- lookup parent from repository -->
</parent>

и добавив следующую зависимость

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>

Мне не нужно было добавлять ничего из следующего, Spring boot делает это сам

  1. @EnableJPAReposity - поскольку у меня уже был весь класс с тем же корневым пакетом
  2. spring.data.jpa.repositories.enabled в application.properties
  3. spring.datasource.driverClassName = com.mysql.jdbc.Driver в свойствах приложения

0

Для всех, кто попал сюда путем поиска в Google общего сообщения об ошибке bean-компонента, но на самом деле пытается добавить имитацию клиента в свое приложение Spring Boot через @FeignClientаннотацию в вашем клиентском интерфейсе, ни одно из вышеперечисленных решений не подойдет вам.

Чтобы решить эту проблему, вам нужно добавить @EnableFeignClientsаннотацию к вашему классу Application, например:

@SpringBootApplication
// ... (other pre-existing annotations) ...
@EnableFeignClients // <------- THE IMPORTANT ONE
public class Application {

Таким образом, исправление похоже на @EnableMongoRepositoriesисправление, упомянутое выше. Жаль, что это общее сообщение об ошибке требует такого индивидуального исправления для каждого типа обстоятельств ...


0

Два типа зависимостей монго -

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-mongodb-reactive</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency> 

Два типа репозиториев -

MongoRepository
ReactiveMongoRepository

Убедитесь, что вы используете правильную комбинацию.


-1

Использование этого решило мою проблему.

@SpringBootApplication(scanBasePackages={"com.example.something", "com.example.application"})
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.