Исключение:Поле studentRepository в com.example.demo.cotroller.Для StudentController требовался компонент типа «com….Репозиторий», который не удалось найти

#mysql #spring-boot #exception #javabeans #autowired

Вопрос:

Я последовал https://spring.io/guides/gs/accessing-data-mysql/#initial за satrt, изучая springboot с MySQL. И я встретил ошибку следующим образом.

 2021-09-23 01:28:31.193  INFO 1196 --- [           main] com.example.demo.DemoApplication         : Starting DemoApplication using Java 1.8.0_144 on DESKTOP-PFH9867 with PID 1196 (C:UsersAdminIdeaProjectsdemotargetclasses started by Admin in C:UsersAdminIdeaProjectsdemo)
2021-09-23 01:28:31.196  INFO 1196 --- [           main] com.example.demo.DemoApplication         : No active profile set, falling back to default profiles: default
2021-09-23 01:28:33.014  INFO 1196 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2021-09-23 01:28:33.027  INFO 1196 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2021-09-23 01:28:33.027  INFO 1196 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.52]
2021-09-23 01:28:33.145  INFO 1196 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2021-09-23 01:28:33.146  INFO 1196 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1875 ms
2021-09-23 01:28:33.218  WARN 1196 --- [           main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'studentController': Unsatisfied dependency expressed through field 'studentRepository'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.example.demo.repository.StudentRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
2021-09-23 01:28:33.221  INFO 1196 --- [           main] o.apache.catalina.core.StandardService   : Stopping service [Tomcat]
2021-09-23 01:28:33.242  INFO 1196 --- [           main] ConditionEvaluationReportLoggingListener : 

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2021-09-23 01:28:33.269 ERROR 1196 --- [           main] o.s.b.d.LoggingFailureAnalysisReporter   : 

***************************
APPLICATION FAILED TO START
***************************

Description:

Field studentRepository in com.example.demo.cotroller.StudentController required a bean of type 'com.example.demo.repository.StudentRepository' that could not be found.

The injection point has the following annotations:
    - @org.springframework.beans.factory.annotation.Autowired(required=true)


Action:

Consider defining a bean of type 'com.example.demo.repository.StudentRepository' in your configuration.


Process finished with exit code 1
 

Очевидно, что главная проблема заключается @Autowired в контроллере. Поэтому я искал множество методов, чтобы справиться с этим. И я не хочу добавлять новый код или новый файл. Как было сказано на веб-сайте при создании репозитория интерфейса, Spring automatically implements this repository interface in a bean that has the same name (with a change in the case — it is called userRepository). поэтому я не хочу добавлять новый код или файл. Я думал, что проблема в моем приложении.свойства или относительном расположении каталогов. Но они совсем не работают.

И мой код выглядит следующим образом.

DemoApplication.java

 package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class  DemoApplication {

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

}
 

Student.java

 package com.example.demo.entity;

import javax.persistence.Entity;

// https://spring.io/guides/gs/accessing-data-mysql/

@Entity // This tells Hibernate to make a table out of this class
public class Student {
    // 2147483647
    private Integer studentID;

    private String name;

    private String department;

    private String major;

    public Integer getStudentID() {
        return studentID;
    }

    public void setStudentID(Integer studentID) {
        this.studentID = studentID;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDepartment() {
        return department;
    }

    public void setDepartment(String department) {
        this.department = department;
    }

    public String getMajor() {
        return major;
    }

    public void setMajor(String major) {
        this.major = major;
    }
}
 

StudentController.java

 package com.example.demo.cotroller;

import com.example.demo.entity.Student;
import com.example.demo.repository.StudentRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

@Controller // This means that this class is a Controller
@RequestMapping(path="/api/v1/student") // This means URL's start with /demo (after Application path)
public class StudentController {
    // This means to get the bean called studentRepository
    // Which is auto-generated by Spring, we will use it to handle the data
    @Autowired
    private StudentRepository studentRepository;

    @PostMapping(path="/add") // Map ONLY POST Requests
    public @ResponseBody
    String addNewUser (@RequestBody Student student) {
        // @ResponseBody means the returned String is the response, not a view name
        // @RequestParam means it is a parameter from the GET or POST request

        studentRepository.save(student);
        return "Saved";
    }
}
 

StudentRepository.java

 package com.example.demo.repository;

import com.example.demo.entity.Student;
import org.springframework.data.repository.CrudRepository;

// This will be AUTO IMPLEMENTED by Spring into a Bean called userRepository
// CRUD refers Create, Read, Update, Delete
public interface StudentRepository extends CrudRepository<Student, Integer> {
}
 

Мои каталоги организованы следующим образом.

 java
|--com.example.demo
   |--controller
      |--StudentController.java
   |--entity
      |--Student.java
   |--repository
      |--StudentRepository.java
   DemoApplication.java   
 

РЕШЕНО!

Наконец-то я нашел истинную причину! Я слишком неосторожен, чтобы следовать учебнику. В нем говорилось, что нажмите «Зависимости» и выберите Spring Web, Spring Data JPA и драйвер MySQL. но я не нажал Spring Data JPA!

Я воссоздал проект, выбрав Spring Web, Spring Data JPA и драйвер MySQL в IDEA, и скопировал файлы, описанные в описании вопроса, после чего проблема решена.

Комментарии:

1. @DhwanilPatel Большое вам спасибо! Я действительно многому у тебя научился 🙂

2. @DhwanilPatel добавьте свои комментарии в качестве ответа, чтобы его можно было проголосовать, принять и «закрыть» вопрос 😉

3. Хорошо, конечно, но обучение и руки помощи важнее, чем голосовать. Спасибо вам обоим. : )

Ответ №1:

Да, вы правы, spring выполняет конфигурацию репозитория рядом с ними, но вы должны сообщить spring, в каком классе вы хотите выполнить или включить эту функциональность. Для этого вам необходимо добавить аннотацию @Repository в свой класс репозитория.

И еще одна вещь для вашего знания. В любом языке структура является неотъемлемой частью любого языка программирования. Чтобы понять это, вы всегда должны следовать лучшим практикам. Здесь вы определили класс репозитория непосредственно в контроллере, что совершенно неправильно. Контроллер предназначен только для управления поступающим запросом и отправки ответа обратно им. Таким образом, такого рода бизнес-логика всегда имеет место в вашем классе обслуживания или классе DaoImpl. Не определяйте объект базы данных в других классах.

Кроме того, если вы работаете с несколькими классами, такими как Пользователь и Отдел, и хотите выполнить какое-либо действие, осуществляется только связь между службами, а не общий доступ к объекту репозитория