'ฟิลด์ต้องการชนิดของถั่วที่หาไม่พบ' error spring restful API โดยใช้ mongodb


101

ดังนั้นฉันจึงเรียนรู้ฤดูใบไม้ผลิในสองสามสัปดาห์ตามบทช่วยสอนนี้

การสร้างบริการเว็บ RESTful

ทุกอย่างเป็นไปด้วยดีจนกระทั่งฉันพยายามรวมเข้ากับ mongodb ดังนั้นฉันจึงทำตามบทแนะนำนี้

การเข้าถึงข้อมูลด้วย MongoDB

แต่การปฏิบัติของฉันบางส่วนยังคงใช้แบบแรก โครงสร้างไดเร็กทอรีโปรเจ็กต์ของฉันจึงเป็นแบบนี้

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

นี่คือไฟล์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;
    }
}

นี่คือไฟล์ที่เหลือของฉัน/ 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' ในคอนฟิกูเรชันของคุณ

ไม่แน่ใจว่าเกิดอะไรขึ้นฉันเริ่ม googling และพบว่าฉันจำเป็นต้องรวมBeans.xmlไฟล์และลงทะเบียน userService ไว้ในนั้น ฉันทำอย่างนั้น แต่มันไม่ได้ผล ฉันใหม่มากสำหรับเรื่องนี้ดังนั้นฉันจึงไม่รู้ว่าเกิดอะไรขึ้น

คำตอบ:


159

แก้ไขได้ ดังนั้นโดยค่าเริ่มต้นแพ็คเกจทั้งหมดที่อยู่ภายใต้@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

@ekaRudianto มีการพิมพ์ผิด ไม่มีการเปิด{สำหรับscanBasePackages= "com.example.something","com.example.application"
brk

ฉันมีปัญหาเดียวกันและพบว่าโครงสร้างแพ็คเกจของฉันไม่อยู่ในลำดับที่เหมาะสม ฉันจัดเรียงใหม่เป็นแบบนี้และตอนนี้ก็ใช้งานได้ดี
Vimukthi Sineth


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 Idea บางครั้งนำเข้า@Serviceจากimport org.jvnet.hk2.annotations.Service;แทนimport org.springframework.stereotype.Service;!


คุณช่วยอัปเดตคำตอบและอธิบายสิ่งที่คุณกำลังทำอยู่ ขอบคุณมากล่วงหน้า
MZaragoza

3
คุณไม่เข้าใจอะไรจากคำตอบของฉันฉันได้รับข้อผิดพลาดเช่นเดียวกับคำถามที่พยายามเรียกใช้โครงการ เป็นเพราะฉันนำเข้าServiceจากห้องสมุดที่ไม่ถูกต้อง
Vitali Kuzmin

@VitaliKuzmin ยังไม่มีความชัดเจนในคำตอบของคุณ คำตอบของคุณอาจถูกต้องและอาจได้ผลสำหรับคุณ แต่วิธีที่คุณนำเสนอในที่นี้นั้นสับสนและไม่เป็นมิตรกับผู้อ่าน
mannedear

3
@mannedear ฉันคิดว่าความคิดเห็นแรกของฉันตอบความคิดเห็นของคุณเช่นกัน
Vitali Kuzmin

+1 คำตอบนี้เนื่องจากฉันทำข้อผิดพลาดในการนำเข้าเช่นกัน! : 0 import javax.persistence.Table;แทนimport org.springframework.data.relational.core.mapping.Table;ในโมเดลของฉัน smh เสียเวลา 5 ชั่วโมงในการดีบักข้อผิดพลาดถั่วนี้
kalpaj agrawalla



5

โดยปกติเราสามารถแก้ปัญหานี้ได้สองด้าน:

  1. ควรใช้คำอธิบายประกอบที่เหมาะสมสำหรับSpring Bootสแกนถั่วเช่น@Component;
  2. สแกนเส้นทางจะรวมถึงการเรียนเช่นเดียวกับคนอื่น ๆ ทั้งหมดดังกล่าวข้างต้น

โดยวิธีการที่มีคำอธิบายที่ดีมากสำหรับความแตกต่างในหมู่@Component, @Repository, @Service และ @Controller



2

การใช้ @ Annotations ทั้งหมดช่วยแก้ปัญหาของฉัน (ใช่ฉันเพิ่งเข้าสู่ 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);
    }

}

และ Repository ของฉันคือ:

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.

ฉันต้องสร้างการใช้งาน mappers ใหม่ด้วย 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 แล้ว
Karen Goh

1

ฉันมีปัญหาเดียวกันกับฉันลบ @Autowired Annotation ออกจากคอนโทรลเลอร์ ถ้าที่เก็บของคุณเป็นคลาสดังนั้น Autowired Annotation จึงจำเป็นต้องใช้ที่เก็บ แต่เมื่อเป็นอินเทอร์เฟซคุณไม่จำเป็นต้องเพิ่ม @Autowired Annotation จากประสบการณ์ของฉัน



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

ชื่อ bean retrofitServiceถูกสร้างขึ้นครั้งแรกและเป็นประเภทGoogleAPIจากนั้นก็ถูกปกคลุมด้วยGithubAPIbecauce ซึ่งทั้งคู่สร้างขึ้นโดยretrofitService()วิธีการ ตอนนี้เมื่อคุณคุณจะได้รับข้อความเหมือน@AutowiredGoogleAPIField googleAPI in com.example.GoogleService required a bean of type 'com.example.rest.GoogleAPI' that could not be found.


0

ในกรณีของฉันฉันเพิ่งใส่ Class 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).

หมายความว่า "ในการทดสอบหน่วยประตูของฉันที่ด้านบนคุณต้องเพิ่มถั่วนั้นด้วยตนเอง"

appContext.putBean(myClass);

0

ฉันทำตามขั้นตอนและคำแนะนำทั้งหมดตามด้วย OP ที่นี่ดูแลช่องว่างรอบ ๆ ชื่อผู้ใช้และรหัสผ่าน (แม้ว่าฤดูใบไม้ผลิจะดูแลช่องว่างในไฟล์คุณสมบัติ) แต่ก็ยังคงเผชิญอยู่

could not find bean for ___Repository

(อินเทอร์เฟซของคุณซึ่งขยาย JPARepository)

หรือหลังจากเพิ่ม @EnableJPARepository

could not find bean for EntityManagerFactory

ฉันแก้ไขได้โดยเปลี่ยนเวอร์ชันหลักของสปริงบูตสตาร์ทเตอร์จาก 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>

ฉันไม่จำเป็นต้องเพิ่มสิ่งต่อไปนี้สปริงบูตทำเอง

  1. @EnableJPAReposity - เนื่องจากฉันมีคลาสทั้งหมดที่มีแพ็คเกจรูทเดียวกันอยู่แล้ว
  2. spring.data.jpa.repositories.enabled ใน application.properties
  3. spring.datasource.driverClassName = com.mysql.jdbc.Driver ในคุณสมบัติของแอปพลิเคชัน

0

สำหรับใครก็ตามที่ถูกพามาที่นี่โดย googling ข้อความแสดงข้อผิดพลาดทั่วไปของ bean แต่ผู้ที่พยายามเพิ่มไคลเอนต์ปลอมไปยังแอปพลิเคชัน Spring Boot ผ่านทาง@FeignClientคำอธิบายประกอบบนอินเทอร์เฟซไคลเอ็นต์ของคุณไม่มีวิธีแก้ปัญหาใด ๆ ข้างต้นที่จะเหมาะกับคุณ

ในการแก้ไขปัญหาคุณต้องเพิ่ม@EnableFeignClientsคำอธิบายประกอบในคลาสแอปพลิเคชันของคุณดังนี้:

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

ด้วยวิธีนี้การแก้ไขจะคล้ายกับการ@EnableMongoRepositoriesแก้ไขที่กล่าวถึงข้างต้น เป็นเรื่องที่น่าเสียดายที่ข้อความแสดงข้อผิดพลาดทั่วไปนี้ต้องการการแก้ไขที่เหมาะสำหรับทุกสถานการณ์ ...


0

การพึ่งพา 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> 

ที่เก็บสองประเภท -

MongoRepository
ReactiveMongoRepository

ตรวจสอบให้แน่ใจว่าคุณใช้ชุดค่าผสมที่เหมาะสม


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.