'O campo exigia um bean do tipo que não foi encontrado.' API error spring restful usando mongodb

104

Estou aprendendo a primavera nos casais da semana, seguindo este tutorial

Construindo um serviço da Web RESTful

Tudo estava bem até que tentei integrá-lo ao mongodb. Então, sigo este tutorial.

Acessando dados com MongoDB

Mas minha prática ainda está parcialmente usando o primeiro. Portanto, minha estrutura de diretório de projeto é assim.

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

Este é meu modelo / arquivo 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;
    }
}

Este é o meu resto / arquivo 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();
    }
}

Este é o meu arquivo 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();
}

Eu poderia compilá-los (estou usando o gradle para compilação porque estou seguindo o tutorial), mas quando executei o arquivo jar ele estava gerando este erro.


APLICAÇÃO FALHOU AO INICIAR


Descrição:

O campo userService em main.java.rest.UsersController exigiu um bean do tipo 'main.java.service.UserService' que não foi encontrado.

Açao:

Considere definir um bean do tipo 'main.java.service.UserService' em sua configuração.

Não tenho certeza do que está errado, comecei a pesquisar no Google e descobri que preciso incluir o Beans.xmlarquivo e registrar o userService nele. Eu fiz isso, mas não está funcionando. Eu sou muito novo nisso, então eu realmente não tenho ideia do que está acontecendo.

Eka Rudianto
fonte

Respostas:

162

Resolvi-o. Portanto, por padrão, todos os pacotes que se enquadram@SpringBootApplication declaração serão verificados.

Supondo que minha classe principal ExampleApplicationque tem @SpringBootApplicationdeclaração seja declarada dentro com.example.something, todos os componentes que se enquadram com.example.somethingsão verificados enquantocom.example.applicant não serão verificados.

Portanto, existem duas maneiras de fazer isso com base nesta pergunta . Usar

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

Dessa forma, o aplicativo fará a varredura de todos os componentes especificados, mas acho que se a escala estivesse ficando maior?

Então eu uso a segunda abordagem, reestruturando meus pacotes e funcionou! Agora minha estrutura de pacotes ficou assim.

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
fonte
nada mudou muito na verdade, eu apenas fiz algumas renomeações dos pacotes e das classes @GuoJing
Eka Rudianto
@ekaRudianto Ocorreu um erro de digitação. Sem abertura {parascanBasePackages= "com.example.something","com.example.application"
brk
Eu também tive o mesmo problema e descobri que a estrutura do meu pacote não estava em ordem. Eu os reorganizei assim e está funcionando bem agora.
Vimukthi Sineth
76

Adicione o @Serviceno serviço / UserService.java.

dzzxjl
fonte
21

Eu também tive o mesmo erro:

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

E meus pacotes foram construídos da mesma forma mencionada na resposta aceita. Corrigi meu problema adicionando a anotação EnableMongoRepositories na classe principal como esta:

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

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

Se você precisar adicionar vários, não se esqueça das chaves:

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

Eu encontrei o mesmo problema e tudo que tive que fazer foi colocar o aplicativo em um pacote um nível acima dos pacotes de serviço, dao e domínio.

Akash Yellappa
fonte
12

Este tópico é antigo, mas estou postando minha resposta, que pode ser útil para outras pessoas.

Eu tive o mesmo problema. Descobriu-se que existe outra classe com o mesmo nome em outro módulo. Eu renomeei essa classe e isso resolveu o problema.

Bhushan Karmarkar
fonte
10

Gastou muito tempo por causa da importação automática. Intellij Idea importou de alguma forma @Serviceem import org.jvnet.hk2.annotations.Service;vez de import org.springframework.stereotype.Service;!

Vitali Kuzmin
fonte
Você poderia atualizar sua resposta e explicar o que está fazendo. Muito obrigado antecipadamente
MZaragoza
3
O que você não entendeu da minha resposta? Recebi o mesmo erro da pergunta, ao tentar executar o projeto. Foi porque importei Serviceda biblioteca errada.
Vitali Kuzmin
@VitaliKuzmin ainda não há clareza em sua resposta. Sua resposta pode estar correta e pode ter funcionado para você, mas a forma como você apresentou aqui é confusa e não amigável ao leitor
mannedear
3
@mannedear Acho que meu primeiro comentário responde ao seu também.
Vitali Kuzmin
Marquei esta resposta com +1, pois também cometi um erro de importação! : 0 em import javax.persistence.Table;vez de import org.springframework.data.relational.core.mapping.Table;no meu modelo. smh perdeu 5 horas na depuração desse erro de bean.
kalpaj agrawalla
9

Você deve adicionar a @Serviceanotação à implementação do seu serviço.

Ahmed AMMOURI
fonte
6

Normalmente podemos resolver esse problema em dois aspectos:

  1. anotações adequadas devem ser usadas para a varredura do Spring Boot no bean , como@Component ;
  2. o caminho de varredura incluirá as classes, assim como todas as outras mencionadas acima.

A propósito, há uma explicação muito boa para a diferença entre @Component, @Repository, @Service e @Controller .

Hearen
fonte
5

Adicione o @Component em sua classe de controlador. Que isso funcione

Shubham Bansal
fonte
3

Adicionar @Repository em sua classe dao

exemplo:

@Repository
public class DaoClassName implements IIntefaceDao {
}
sonOFAthena
fonte
2

Usar todas as anotações @ corrigiu meu problema. (Sim, sou novo no Spring) Se você estiver usando uma classe de serviço, adicione @Service e o mesmo para @Controller e @Repository.

Então, essas anotações no App.java corrigiram o problema (estou usando JPA + Hibernate)

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

Árvore de pacotes:

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
Caxemira 54
fonte
2

Eu tenho o mesmo problema, corrigido pela adição de @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);
    }

}

E meu Repositório é:

package in.topthree.util;

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

public interface StudentMongo extends MongoRepository<Student, Integer> {

    public Student findByUrl(String url);
}

Agora está funcionando

Ahmad
fonte
2

Eu tive o mesmo problema. Meu erro foi usar a anotação @Service na interface de serviço. A anotação @Service deve ser aplicada à classe ServiceImpl.

Ashish Singh
fonte
2

Eu tive o mesmo problema de remover a anotação @Autowired do controlador. Se o seu repositório for uma classe, a anotação Autowired é necessária para usar o repositório, mas quando for uma interface, você não precisa adicionar a anotação @Autowired por experiência própria.

Mumbasa
fonte
1

Minhas classes de implementação do Mapper em minha pasta de destino foram excluídas, então minhas interfaces do Mapper não tinham mais classes de implementação. Portanto, obtive o mesmo erroField *** required a bean of type ***Mapper that could not be found.

Eu simplesmente tive que regenerar minhas implementações de mapeadores com o maven e atualizar o projeto ...

RotS
fonte
1

Eu vim para este post em busca de ajuda ao usar Spring Webflux com o Mongo Repository.

Meu erro foi semelhante ao do proprietário

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

Como eu estava trabalhando antes com Spring MVC, fiquei surpreso com esse erro.

Como encontrar ajuda não era tão óbvio, estou respondendo a esta pergunta, pois de alguma forma está relacionada e esta pergunta está no topo dos resultados de pesquisa.

A primeira coisa é que você deve se lembrar do que foi mencionado na resposta marcada como aceita - hierarquia de pacotes.

A segunda coisa importante é que se você usar o Webflux, você precisa usar algum pacote diferente ao usar o Spring MVC, por exemplo, para MongoDB, você precisa adicionar

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

com -reactive no final.

Łukasz Kotyński
fonte
1

Adicione @Repository em sua classe dao

    @Repository
    public interface UserDao extends CrudRepository<User, Long> {
         User findByUsername(String username);
         User findByEmail(String email);    
      }
biddut
fonte
não há necessidade de adicionar @Repository se você já estende CrudRepository
Karen Goh
1

você tem que importar spring-boot-starter-data-jpa como dependeny se você usar spring boot

Duracell
fonte
1

A fim de criar o bean e injetá-lo, a classe deve ser marcada com @ Componet, @ service, @ Repository etc em seu contexto, deve ser

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

Isso pode acontecer quando dois grãos têm os mesmos nomes.

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

Um bean denominado retrofitServiceé primeiro criado e seu tipo é GoogleAPI, então coberto por um GithubAPIporque ambos são criados por um retrofitService()método. Agora, quando você @Autowiredum GoogleAPIvocê receber uma mensagem comoField googleAPI in com.example.GoogleService required a bean of type 'com.example.rest.GoogleAPI' that could not be found.

benymor
fonte
0

No meu caso, acabei de colocar a classe MyprojectApplication em um pacote (com.example.start) com o mesmo nível de modelo, controlador, pacotes de serviço.

Zain Elabidine
fonte
0

Eu sei que é antigo, mas quero adicionar meus 5 centavos.

Usei .servicee .service.implem uma estrutura de pasta para separar o serviço com sua implementação. Esqueça de implementar a parte ServiceImplementation.

Cyber
fonte
0

Para mim esta mensagem:

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

significava "no meu teste de unidade do postigo no topo, você tem que adicionar manualmente esse feijão como"

appContext.putBean(myClass);
rogerdpack
fonte
0

Eu segui todas as etapas e instruções seguidas pelo OP aqui, cuidei do espaço em branco ao redor do nome de usuário e senha (embora o spring cuide dos espaços em branco no arquivo de propriedades), ainda estava voltado para

could not find bean for ___Repository

(sua interface que estende JPARepository)

OU depois de adicionar @EnableJPARepository

could not find bean for EntityManagerFactory

Eu resolvi isso mudando a versão principal do spring boot starter de 2.3.2 para 2.2.1 em 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>

e adicionar a seguinte dependência

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

Não precisei adicionar nenhum dos itens a seguir, a bota de mola faz isso sozinha

  1. @EnableJPAReposity - uma vez que já tinha todas as classes com o mesmo pacote raiz
  2. spring.data.jpa.repositories.enabled em application.properties
  3. spring.datasource.driverClassName = com.mysql.jdbc.Driver nas propriedades do aplicativo
Shubham Debnath
fonte
0

Para qualquer um que foi trazido aqui pesquisando a mensagem de erro do bean genérico, mas que está realmente tentando adicionar um cliente simulado ao aplicativo Spring Boot por meio do@FeignClient anotação na interface do cliente, nenhuma das soluções acima funcionará para você.

Para corrigir o problema, você precisa adicionar a @EnableFeignClientsanotação à sua classe Application, assim:

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

Desta forma, a correção é semelhante à @EnableMongoRepositoriescorreção mencionada acima. É uma pena que esta mensagem de erro genérica exija uma correção personalizada para cada tipo de circunstância ...

Eriegz
fonte
0

Dois tipos de dependências 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> 

Dois tipos de repositórios -

MongoRepository
ReactiveMongoRepository

Certifique-se de usar a combinação certa.

Akshay Kharade
fonte
-1

Usar isso resolveu meu problema.

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