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

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

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.


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

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.


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.


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


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.


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 .



3

Adicionar @Repository em sua classe dao

exemplo:

@Repository
public class DaoClassName implements IIntefaceDao {
}

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

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


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.


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.


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


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.


1

Adicione @Repository em sua classe dao

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

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


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

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.


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.


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.


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

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

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


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.


-1

Usar isso resolveu meu problema.

@SpringBootApplication(scanBasePackages={"com.example.something", "com.example.application"})
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.