„Pole wymagało fasoli typu, którego nie można znaleźć”. błąd sprężyny restful API przy użyciu mongodb

104

Tak więc uczyłem się wiosny w parach tygodnia, postępując zgodnie z tym samouczkiem

Tworzenie usługi sieci Web zgodnej z REST

Wszystko było dobrze, dopóki nie spróbowałem zintegrować go z mongodb. Więc podążam za tym samouczkiem.

Dostęp do danych w MongoDB

Ale moja praktyka częściowo nadal używa pierwszej. Więc struktura katalogów mojego projektu jest taka.

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

To jest mój plik model / 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;
    }
}

To jest mój plik 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();
    }
}

To jest mój plik usługi / 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();
}

Mógłbym je skompilować (używam gradle do kompilacji, ponieważ postępuję zgodnie z tutorialem), ale kiedy uruchamiam plik jar, zgłaszał ten błąd.


APLIKACJA NIE URUCHOMIONA


Opis:

Pole userService w main.java.rest.UsersController wymagało komponentu bean typu „main.java.service.UserService”, którego nie można znaleźć.

Akcja:

Rozważ zdefiniowanie komponentu bean typu „main.java.service.UserService” w swojej konfiguracji.

Nie jestem pewien, co jest nie tak, zaczynam googlować i stwierdziłem, że muszę dołączyć Beans.xmlplik i zarejestrować w nim usługę userService. Zrobiłem to, ale to nie działa. Jestem w tym naprawdę nowy, więc nie mam pojęcia, co się dzieje.

Eka Rudianto
źródło

Odpowiedzi:

163

Rozwiązałem to. Dlatego domyślnie wszystkie pakiety objęte @SpringBootApplicationdeklaracją zostaną przeskanowane.

Zakładając, że moja główna klasa, ExampleApplicationktóra ma @SpringBootApplicationdeklarację, jest zadeklarowana w środku com.example.something, wszystkie komponenty, które należą do niej, com.example.somethingsą skanowane, podczas gdy com.example.applicantnie będą skanowane.

W oparciu o to pytanie można to zrobić na dwa sposoby . Posługiwać się

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

W ten sposób aplikacja przeskanuje wszystkie podane komponenty, ale myślę, że co by było, gdyby skala się powiększała?

Więc używam drugiego podejścia, restrukturyzacji moich pakietów i zadziałało! Teraz struktura moich pakietów wyglądała następująco.

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
Eka Rudianto
źródło
właściwie nic się nie zmieniło, właśnie zmieniłem nazwy pakietów i klas @GuoJing
Eka Rudianto
@ekaRudianto Wystąpiła literówka. Brak otwarcia {nascanBasePackages= "com.example.something","com.example.application"
brk
Miałem również ten sam problem i stwierdziłem, że struktura mojego pakietu nie jest w odpowiedniej kolejności. Przestawiłem je w ten sposób i teraz działa dobrze.
Vimukthi Sineth
76

Dodaj @Servicew usłudze / UserService.java.

dzzxjl
źródło
21

Miałem też ten sam błąd:

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

A moje pakiety zostały skonstruowane w taki sam sposób, jak wspomniano w zaakceptowanej odpowiedzi. Naprawiłem mój problem, dodając adnotację EnableMongoRepositories w głównej klasie w następujący sposób:

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

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

Jeśli chcesz dodać wiele, nie zapomnij o nawiasach klamrowych:

@EnableMongoRepositories(basePackageClasses
    = {
        MSASMSRepository.class, APartyMappingRepository.class
    })
brudny
źródło
14

Napotkałem ten sam problem i wszystko, co musiałem zrobić, to umieścić Aplikację w pakiecie o jeden poziom wyżej niż pakiety usług, dao i domeny.

Akash Yellappa
źródło
12

Ten wątek jest już stary, ale zamieszczam swoją odpowiedź, która może być przydatna dla innych.

Miałem ten sam problem. Okazało się, że w innym module jest inna klasa o tej samej nazwie. Zmieniłem nazwę tej klasy i rozwiązałem problem.

Bhushan Karmarkar
źródło
10

Spędziłem dużo czasu z powodu automatycznego importu. Intellij Idea nieco zaimportowana @Servicez import org.jvnet.hk2.annotations.Service;zamiast import org.springframework.stereotype.Service;!

Vitali Kuzmin
źródło
Czy mógłbyś zaktualizować swoją odpowiedź i wyjaśnić, co robisz. Z góry
wielkie
3
Czego nie zrozumiałeś z mojej odpowiedzi? Otrzymałem ten sam błąd co w pytaniu, próbując uruchomić projekt. To dlatego, że zaimportowałem Servicez niewłaściwej biblioteki.
Vitali Kuzmin
@VitaliKuzmin nadal nie ma jasności w Twojej odpowiedzi. Twoja odpowiedź może być prawidłowa, a może pracował dla ciebie, ale sposób, w jaki przedstawiony tutaj jest niejasna i nie przyjazne czytelnikowi
mannedear
3
@mannedear Myślę, że mój pierwszy komentarz jest również odpowiedzią na Twój komentarz.
Vitali Kuzmin
Dał +1 tej odpowiedzi, ponieważ również popełniłem błąd importu! : 0 import javax.persistence.Table;zamiast import org.springframework.data.relational.core.mapping.Table;w moim modelu. smh stracił 5 godzin na debugowaniu tego błędu fasoli.
kalpaj agrawalla
9

Musisz dodać @Serviceadnotację do realizacji swojej usługi.

Ahmed AMMOURI
źródło
6

Zwykle możemy rozwiązać ten problem w dwóch aspektach:

  1. właściwa adnotacja powinna być wykorzystywane do wiosny Boot skanowanie fasoli , jak@Component .;
  2. skanowania ścieżka obejmie zajęcia tak jak wszyscy inni, o których mowa powyżej.

Nawiasem mówiąc, istnieje bardzo dobre wyjaśnienie różnicy między @Component, @Repository, @Service i @Controller .

Hearen
źródło
5

Dodaj @Component do swojej klasy kontrolera. Niech to zadziała

shubham bansal
źródło
3

Dodaj @Repository w swojej klasie dao

przykład:

@Repository
public class DaoClassName implements IIntefaceDao {
}
sonOFAthena
źródło
2

Użycie wszystkich adnotacji @ rozwiązało mój problem. (Tak, jestem nowy w Spring) Jeśli używasz klasy usług, dodaj @Service i to samo dla @Controller i @Repository.

Następnie te adnotacje w App.java rozwiązały problem (używam JPA + Hibernate)

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

Drzewo pakietów:

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
Kaszmir54
źródło
2

Mam ten sam problem, rozwiązany przez dodanie @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);
    }

}

A moje repozytorium to:

package in.topthree.util;

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

public interface StudentMongo extends MongoRepository<Student, Integer> {

    public Student findByUrl(String url);
}

Teraz to działa

Ahmad
źródło
2

Miałem ten sam problem. Mój błąd polegał na tym, że użyłem adnotacji @Service w interfejsie usługi. Adnotację @Service należy zastosować do klasy ServiceImpl.

Ashish Singh
źródło
2

Miałem ten sam problem, że usunąłem adnotację @Autowired ze sterownika. Jeśli twoje repozytorium jest klasą, do korzystania z repozytorium potrzebna jest adnotacja Autowired, ale gdy jest to interfejs, nie musisz dodawać adnotacji @Autowired z mojego doświadczenia.

mumbasa
źródło
1

Moje klasy implementacji Mappera w folderze docelowym zostały usunięte, więc moje interfejsy Mappera nie miały już klas implementacji. W ten sposób otrzymałem ten sam błądField *** required a bean of type ***Mapper that could not be found.

Po prostu musiałem zregenerować moje implementacje mapperów za pomocą maven i odświeżyć projekt ...

RotS
źródło
1

Przyszedłem do tego posta, szukając pomocy przy używaniu Spring Webflux z Mongo Repository.

Mój błąd był podobny do właściciela

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

Ponieważ pracowałem wcześniej z Spring MVC, byłem zaskoczony tym błędem.

Ponieważ znalezienie pomocy nie było takie oczywiste, odpowiadam na to pytanie, ponieważ jest w jakiś sposób powiązane i to pytanie jest wysoko w wynikach wyszukiwania.

Przede wszystkim należy pamiętać o tym, co w odpowiedzi zostało zaznaczone jako zaakceptowane - hierarchia paczek.

Drugą ważną rzeczą jest to, że jeśli używasz Webflux, musisz użyć innego pakietu podczas korzystania z Spring MVC, np. Dla MongoDB, musisz dodać

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

z -reactive na końcu.

Łukasz Kotyński
źródło
1

Dodaj @Repository do swojej klasy dao

    @Repository
    public interface UserDao extends CrudRepository<User, Long> {
         User findByUsername(String username);
         User findByEmail(String email);    
      }
biddut
źródło
nie ma potrzeby dodawania @Repository, jeśli już rozszerzyłeś CrudRepository
Karen Goh
1

musisz zaimportować spring-boot-starter-data-jpa jako dependeny, jeśli używasz spring boot

duracell
źródło
1

Aby utworzyć bean i wstrzyknąć go, klasa powinna być oznaczona @ Componet, @ service, @ Repository itp. W Twoim kontekście powinna być

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();
}
Anwar Sir
źródło
0

Może się tak zdarzyć, gdy dwie fasole mają takie same nazwy.

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

retrofitServiceNajpierw tworzony jest fasolka o nazwie , której typ jest GoogleAPI, a następnie objęta tym, GithubAPIże oba zostały utworzone za pomocą retrofitService()metody. Teraz, kiedy otrzymasz taką wiadomość@AutowiredGoogleAPIField googleAPI in com.example.GoogleService required a bean of type 'com.example.rest.GoogleAPI' that could not be found.

benymor
źródło
0

W moim przypadku właśnie umieściłem Class MyprojectApplication w pakiecie (com.example.start) z tym samym poziomem modelu, kontrolera, pakietów usług.

Zain Elabidine
źródło
0

Wiem, że jest stary, ale chcę dodać moje 5 centów.

Użyłem .servicei .service.implw strukturze folderów, aby oddzielić usługę od jej implementacji. Zapomnij o implementacji elementu ServiceImplementation.

Cyber
źródło
0

Dla mnie ta wiadomość:

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).

oznaczało „w moim teście jednostki furtki na górze musisz ręcznie dodać tę fasolę w polubieniu”

appContext.putBean(myClass);
rogerdpack
źródło
0

Wykonałem wszystkie kroki i instrukcje, a następnie OP tutaj, zadbałem o puste miejsce wokół nazwy użytkownika i hasła (mimo że spring dba o białe spacje w pliku właściwości), nadal był skierowany

could not find bean for ___Repository

(Twój interfejs, który rozszerza JPARepository)

LUB po dodaniu @EnableJPARepository

could not find bean for EntityManagerFactory

rozwiązałem to, zmieniając wersję rodzica rozruchowego rozruchu sprężynowego z 2.3.2 na 2.2.1 w 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>

i dodając następującą zależność

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

Nie musiałem dodawać żadnego z poniższych, sprężynowy but robi to sam

  1. @EnableJPAReposity - ponieważ miałem już wszystkie klasy z tym samym pakietem głównym
  2. spring.data.jpa.repositories.enabled w application.properties
  3. spring.datasource.driverClassName = com.mysql.jdbc.Driver we właściwościach aplikacji
Shubham Debnath
źródło
0

Dla każdego, kto został przywieziony tutaj przez wygooglowanie ogólnego komunikatu o błędzie fasoli, ale który faktycznie próbuje dodać pozorowanego klienta do swojej aplikacji Spring Boot za pośrednictwem@FeignClient adnotacji w interfejsie klienta, żadne z powyższych rozwiązań nie zadziała.

Aby rozwiązać problem, musisz dodać @EnableFeignClientsadnotację do swojej klasy Application, na przykład:

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

W ten sposób poprawka jest podobna do @EnableMongoRepositorieswspomnianej powyżej. Szkoda, że ​​ten ogólny komunikat o błędzie wymaga tak dostosowanej poprawki w każdych okolicznościach ...

eriegz
źródło
0

Dwa rodzaje zależności mongo -

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

Dwa rodzaje repozytoriów -

MongoRepository
ReactiveMongoRepository

Upewnij się, że używasz właściwej kombinacji.

Akshay kharade
źródło
-1

Korzystanie z tego rozwiązało mój problem.

@SpringBootApplication(scanBasePackages={"com.example.something", "com.example.application"})
Anand
źródło