'El campo requería un bean de tipo que no se pudo encontrar.' API de descanso de primavera de error usando mongodb

101

Así que he estado aprendiendo Spring en las parejas de la semana, siguiendo este tutorial

Construyendo un servicio web RESTful

Todo iba bien hasta que intenté integrarlo en mongodb. Entonces sigo este tutorial.

Acceder a datos con MongoDB

Pero mi práctica todavía usa parcialmente el primero. Entonces, la estructura de directorio de mi proyecto es así.

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

Este es mi modelo / archivo 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 es mi archivo 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();
    }
}

Este es mi archivo 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();
}

Podría compilarlos (estoy usando gradle para la compilación porque estoy siguiendo el tutorial), pero cuando ejecuto el archivo jar estaba arrojando este error.


LA APLICACIÓN NO SE PUEDE INICIAR


Descripción:

El campo userService en main.java.rest.UsersController requería un bean de tipo 'main.java.service.UserService' que no se pudo encontrar.

Acción:

Considere definir un bean de tipo 'main.java.service.UserService' en su configuración.

No estoy seguro de qué está mal, empiezo a buscar en Google y descubrí que necesito incluir el Beans.xmlarchivo y registrar el servicio de usuario en él. Hice eso pero no está funcionando. Soy realmente nuevo en esto, así que no tengo ni idea de lo que está pasando.

Eka Rudianto
fuente

Respuestas:

159

Resuelto. Entonces, de forma predeterminada, @SpringBootApplicationse escanearán todos los paquetes incluidos en la declaración.

Suponiendo que mi clase principal ExampleApplicationque tiene una @SpringBootApplicationdeclaración esté declarada dentro com.example.something, todos los componentes que caen debajo com.example.somethingse escanean mientras com.example.applicantno se escanearán.

Entonces, hay dos formas de hacerlo en función de esta pregunta . Utilizar

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

De esa manera, la aplicación escaneará todos los componentes especificados, pero creo que ¿qué pasaría si la escala se hiciera más grande?

Así que utilizo el segundo enfoque, reestructurando mis paquetes y ¡funcionó! Ahora la estructura de mis paquetes se volvió así.

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
fuente
nada cambió mucho en realidad, acabo de cambiar el nombre de los paquetes y las clases @GuoJing
Eka Rudianto
@ekaRudianto Hay un error tipográfico. No hay apertura {parascanBasePackages= "com.example.something","com.example.application"
brk
También tuve el mismo problema y descubrí que la estructura de mi paquete no estaba en el orden correcto. Los reorganicé así y ahora está funcionando bien.
Vimukthi Sineth
73

Agregue el @Serviceen el servicio / UserService.java.

dzzxjl
fuente
20

También tuve el mismo error:

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

Y mis paquetes se construyeron de la misma manera que se menciona en la respuesta aceptada. Solucioné mi problema agregando la anotación EnableMongoRepositories en la clase principal de esta manera:

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

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

Si necesita agregar varios, no olvide las llaves:

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

Encontré el mismo problema y todo lo que tuve que hacer fue colocar la Aplicación en un paquete un nivel más alto que los paquetes de servicio, dao y dominio.

Akash Yellappa
fuente
12

Este hilo es antiguo ahora, pero estoy publicando mi respuesta, que puede ser útil para otros.

Tuve el mismo problema. Resultó que hay otra clase con el mismo nombre en otro módulo. Cambié el nombre de esa clase y resolvió el problema.

Bhushan Karmarkar
fuente
10

Pasó mucho tiempo debido a la importación automática. Intellij Idea de alguna manera importada @Serviceen import org.jvnet.hk2.annotations.Service;lugar de import org.springframework.stereotype.Service;!

Vitali Kuzmin
fuente
¿Podría actualizar su respuesta y explicar lo que está haciendo? Muchas gracias de antemano
MZaragoza
3
¿Qué no entendiste de mi respuesta? Recibí el mismo error que en la pregunta, al intentar ejecutar el proyecto. Fue porque importé Servicede la biblioteca incorrecta.
Vitali Kuzmin
@VitaliKuzmin todavía no hay claridad en su respuesta. Su respuesta puede ser correcta y puede haber trabajado para usted, pero la forma en que se presenta aquí es confuso y no de fácil lectura
mannedear
3
@mannedear Creo que mi primer comentario también responde al tuyo.
Vitali Kuzmin
Hice +1 en esta respuesta, ¡ya que también cometí un error de importación! : 0 en import javax.persistence.Table;lugar de import org.springframework.data.relational.core.mapping.Table;en mi modelo. smh perdió 5 horas en la depuración de este error de bean.
kalpaj agrawalla
8

Tienes que agregar la @Serviceanotación a la implementación de tu servicio.

Ahmed AMMOURI
fuente
5

Agregue el @Component en su clase de controlador. Que esto funcione

shubham bansal
fuente
5

Normalmente podemos solucionar este problema en dos aspectos:

  1. la anotación adecuada debe usarse para Spring Boot escaneando el bean , como @Component;
  2. la ruta de exploración incluirá las clases al igual que todas las demás mencionadas anteriormente.

Por cierto, hay una muy buena explicación para la diferencia entre @Component, @Repository, @Service y @Controller .

Hearen
fuente
3

Agregue @Repository en su clase dao

ejemplo:

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

El uso de todas las @ Anotaciones solucionó mi problema. (Sí, soy nuevo en Spring) Si está utilizando una clase de servicio, agregue @Service, y lo mismo para @Controller y @Repository.

Luego, estas anotaciones en App.java solucionaron el problema (estoy usando JPA + Hibernate)

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

Árbol de paquetes:

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
Cachemira54
fuente
2

Tengo el mismo problema, solucionado agregando @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);
    }

}

Y mi repositorio es:

package in.topthree.util;

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

public interface StudentMongo extends MongoRepository<Student, Integer> {

    public Student findByUrl(String url);
}

Ahora funciona

Ahmad
fuente
1

Mis clases de implementación de Mapper en mi carpeta de destino se habían eliminado, por lo que mis interfaces de Mapper ya no tenían clases de implementación. Por eso tengo el mismo errorField *** required a bean of type ***Mapper that could not be found.

Simplemente tuve que regenerar mis implementaciones de mapeadores con maven y actualizar el proyecto ...

Putrefacción
fuente
1

Vine a esta publicación en busca de ayuda mientras usaba Spring Webflux con Mongo Repository.

Mi error fue similar al propietario

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

Como estaba trabajando antes con Spring MVC, me sorprendió este error.

Debido a que encontrar ayuda no fue tan obvio, estoy respondiendo a esta pregunta, ya que de alguna manera está relacionada y esta pregunta ocupa un lugar destacado en los resultados de búsqueda.

Lo primero es que debe recordar lo que se mencionó en la respuesta marcada como aceptada: jerarquía de paquetes.

La segunda cosa importante es que si usa Webflux necesita usar algún paquete diferente mientras usa Spring MVC, por ejemplo, para MongoDB debe agregar

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

con -reactivo al final.

Łukasz Kotyński
fuente
1

Tuve el mismo problema. Mi error fue que utilicé la anotación @Service en la interfaz de servicio. La anotación @Service debe aplicarse a la clase ServiceImpl.

Ashish Singh
fuente
1

Agregue @Repository en su clase dao

    @Repository
    public interface UserDao extends CrudRepository<User, Long> {
         User findByUsername(String username);
         User findByEmail(String email);    
      }
biddut
fuente
no es necesario agregar @Repository si ya extiende CrudRepository
Karen Goh
1

Tuve el mismo problema, eliminé la anotación @Autowired del controlador. Si su repositorio es una clase, entonces se necesita la Anotación Autowired para usar el repositorio, pero cuando es una interfaz, no es necesario agregar la Anotación @Autowired de mi experiencia.

mumbasa
fuente
1

tienes que importar spring-boot-starter-data-jpa como dependencia si usas spring boot

duracell
fuente
0

Esto puede suceder cuando dos frijoles tienen el mismo nombre.

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

retrofitServicePrimero se crea un bean con nombre , y su tipo es GoogleAPI, luego se cubre con un GithubAPIporque ambos son creados por un retrofitService()método. Ahora, cuando @Autowiredun GoogleAPIobtendrá un mensaje comoField googleAPI in com.example.GoogleService required a bean of type 'com.example.rest.GoogleAPI' that could not be found.

benymor
fuente
0

En mi caso, acabo de poner la Class MyprojectApplication en un paquete (com.example.start) con el mismo nivel de modelo, controlador, paquetes de servicio.

Zain Elabidine
fuente
0

Sé que es viejo, pero quiero agregar mis 5 centavos.

Usé .servicey .service.implen una estructura de carpetas para separar el servicio con su implementación. Olvídese de implementar la pieza ServiceImplementation.

Cyber
fuente
0

Para poder crear un bean e inyectarlo, la clase debe estar marcada con @ Componet, @ service, @ Repository, etc. de acuerdo con el contexto en su contexto, debe 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();
}
Señor Anwar
fuente
0

Para mi este mensaje:

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

significaba "en mi prueba de unidad de ventanilla en la parte superior, tienes que agregar manualmente ese frijol como"

appContext.putBean(myClass);
Rogerdpack
fuente
0

Seguí todos los pasos e instrucciones seguidos por OP aquí, me ocupé del espacio en blanco alrededor del nombre de usuario y la contraseña (a pesar de que Spring se ocupa de los espacios en blanco en el archivo de propiedades), todavía estaba enfrentando

could not find bean for ___Repository

(interfaz que extiende JPARepository)

O después de agregar @EnableJPARepository

could not find bean for EntityManagerFactory

Lo resolví cambiando la versión principal de Spring Boot Starter de 2.3.2 a 2.2.1 en 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>

y agregando la siguiente dependencia

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

No necesitaba agregar nada de lo siguiente, el arranque de primavera lo hace solo

  1. @EnableJPAReposity - ya que ya tenía todas las clases con el mismo paquete raíz
  2. spring.data.jpa.repositories.enabled en application.properties
  3. spring.datasource.driverClassName = com.mysql.jdbc.Driver en las propiedades de la aplicación
Shubham Debnath
fuente
0

Para cualquiera que haya sido traído aquí al buscar en Google el mensaje de error genérico del bean, pero que en realidad esté intentando agregar un cliente fingido a su aplicación Spring Boot a través de la @FeignClientanotación en la interfaz de su cliente, ninguna de las soluciones anteriores funcionará para usted.

Para solucionar el problema, debe agregar la @EnableFeignClientsanotación a su clase de aplicación, así:

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

De esta manera, la solución es similar a la @EnableMongoRepositoriesmencionada anteriormente. Es una pena que este mensaje de error genérico requiera una solución tan personalizada para cada tipo de circunstancia ...

eriegz
fuente
0

Dos tipos de dependencias de 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> 

Dos tipos de repositorios:

MongoRepository
ReactiveMongoRepository

Asegúrate de usar la combinación correcta.

Akshay kharade
fuente
-1

Usar esto resolvió mi problema.

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