Простой SpringBoot, карта памяти, контроллер REST, операции CRUD

У меня ситуация, когда я не могу понять, в чем может быть проблема. Ниже приведены подробности. Я могу запустить приложение весенней загрузки и сохранять записи. Однако при попытке выполнить операции CRUD через Rest Controller. При попытке получить записи из карты в памяти я получаю ответ 200 ОК без самих данных. Хотя я могу получить ответ строки («Hello World»)

Что я делаю не так? Я не думаю, что внедрение объектов является проблемой в классе Controller. Пожалуйста, предложите.TIA. подробности ниже:

Мое основное приложение:

@ComponentScan("com.someone.organization")
@SpringBootApplication
public class WorkingOrganizationApplication {

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

        @SuppressWarnings("resource")
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
        context.scan("com.someone.organization");
        context.refresh();

        
        EmployeeRepository empRepository = context.getBean(EmployeeRepository.class);
         //testing the store method
        empRepository.save(new Employee(1L, "XYZ","PQR"));
        empRepository.save(new Employee(2L, "ABC","PQR"));
        empRepository.save(new Employee(3L, "MNC","PQR"));


        Employee employee = empRepository.findById(1L);
        System.out.println(employee.toString());
  

        Employee employee2 = empRepository.findById(2L);
        System.out.println(employee2.toString());
        // close the spring context
        context.close();
    
    }

}

мой класс Entity:

public class Employee {

    private Long Employee_Id;

    @Override
    public String toString() {
        return "Employee{" +
                "Employee_Id = " + Employee_Id +
                ", Employee_first_name='" + Employee_first_name + '\'' +
                ", Employee_last_name='" + Employee_last_name + '\'' +
                '}';
    }

    private String Employee_first_name;

    private String Employee_last_name;


    public Long getEmployeeId() {
        return Employee_Id;
    }

    public void setEmployee_Id(Long employee_Id) {
        Employee_Id = employee_Id;
    }

    public String getEmployee_first_name() {
        return Employee_first_name;
    }

    public void setEmployee_first_name(String employee_first_name) {
        Employee_first_name = employee_first_name;
    }

    public String getEmployee_last_name() {
        return Employee_last_name;
    }

    public void setEmployee_last_name(String employee_last_name) {
        Employee_last_name = employee_last_name;
    }

    public Employee(Long employee_Id, String employee_first_name, String employee_last_name) {

        this.Employee_Id = employee_Id;

        this.Employee_first_name = employee_first_name;
        this.Employee_last_name = employee_last_name;
    }


}

мой интерфейс репозитория данных:

public interface OrganizationRepository<T> {

      // Save method
      void save(T entity);

      // Find a employee by its id
      Employee findById(Long id);


      //public List<Employee> findAllEmployees();

}

мой класс реализации репозитория

@Repository
public class EmployeeRepository implements OrganizationRepository<Employee> {

    private final Map<Long, Employee> repository;

    public EmployeeRepository() {
        this.repository = new HashMap<>();
    }

    @Override
    public void save(Employee employee) {

        // repository.put(id, employee);
        repository.put(employee.getEmployeeId(), employee);

    }

    @Override
    public Employee findById(Long id) {

        Employee employeeOutput = null;
        if (repository.containsKey(id)) {
            employeeOutput = repository.get(id);
        }

        return employeeOutput;
    }

    
}

мой класс контроллера

@RestController
public class EmployeeController {

    @Autowired
    private EmployeeRepository  employeeRepository;

    @PostMapping("/employees")
    public Employee createEmployee(@RequestBody Employee employee) {
         employeeRepository.save(employee);
         return  employee;
    }

    @GetMapping("/employees/findbyid/{id}")
    public Employee getEmployee(@PathVariable Long id) {

      
      return employeeRepository.findById(id);
        
    }

    @GetMapping("/hello")
    public String hello() {
        return "Hello, World!";
    }
}

Тот факт, что у вас есть @ComponentScan, вызывает беспокойство, у вас этого быть не должно. И твой main неправильный. Удалите конструкцию и обновите ApplicationContext. SpringBootApplication.run`, который уже запускает ваше приложение и возвращает ApplicationContext, используйте его вместо этого.

M. Deinum 19.02.2024 16:18
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Версия Java на основе версии загрузки
Версия Java на основе версии загрузки
Если вы зайдете на официальный сайт Spring Boot , там представлен start.spring.io , который упрощает создание проектов Spring Boot, как показано ниже.
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
1
1
74
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Проблема в вашем main методе. По сути, вы загружаете контекст дважды и, таким образом, используете несколько разных экземпляров EmployeeRepository.

SpringApplication.run(WorkingOrganizationApplication.class, args);

Эта строка уже загружает и запускает ваше приложение, и если вы посмотрите на метод run, вы увидите, что он уже возвращает ApplicationContext, который вы можете (и должны использовать).

@SuppressWarnings("resource")
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.scan("com.someone.organization");
context.refresh();

Этот небольшой фрагмент кода снова загружает все классы и создает новые экземпляры. Это не то, что вам нужно, если только вы не хотите проблем с памятью и других трудно прогнозируемых проблем (как сейчас, когда обновления/вставки исчезли).

Вам следует написать что-то в этом роде.

public static void main(String[] args) {
    ApplicationContext context = SpringApplication.run(WorkingOrganizationApplication.class, args);
   
    EmployeeRepository empRepository = context.getBean(EmployeeRepository.class);
     //testing the store method
    empRepository.save(new Employee(1L, "XYZ","PQR"));
    empRepository.save(new Employee(2L, "ABC","PQR"));
    empRepository.save(new Employee(3L, "MNC","PQR"));

    Employee employee = empRepository.findById(1L);
    System.out.println(employee);

    Employee employee2 = empRepository.findById(2L);
    System.out.println(employee2);
}

Вам также не следует добавлять @ComponentScan все ваши классы уже должны быть в пакете com.someone.organization, включая аннотированный класс @SpringBootApplication. Он уже начнет сканирование из этого пакета.

Как правило, с Spring (Boot) меньше значит лучше, не пытайтесь быть умнее фреймворка.

Спасибо, @Deinum. Почему мне нужно создавать bean-компонент исключительно с использованием AppContext здесь? Могу ли я не автоматически подключить СотрудникиРепозиторий как зависимость в основном классе?

crcr 19.02.2024 19:45

Нет, поскольку вы не можете автоматически подключаться к статическому полю. Вы можете подключить его к другому классу.

M. Deinum 21.02.2024 08:25

Почему мне нужно создавать здесь bean-компонент исключительно с использованием AppContext? Могу ли я не автоматически подключить СотрудникиРепозиторий как зависимость в основном классе? Отвечая на мой вопрос здесь: Как обновлено ниже: мы можем использовать нестатический блок @PostConstruct, который выполняется сразу после инициализации свойств компонента. Обычно используется заполнение базы данных. Например, во время разработки мы можем захотеть создать некоторых пользователей по умолчанию в нашей базе данных/хранилище данных.

@SpringBootApplication
public class WorkingOrganizationApplication {

    @Autowired
    private  EmployeeRepository empRepository;


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

    @PostConstruct
    public void execute()
    {
        empRepository.save(new Employee(1L, "XYZ","PQR"));
        empRepository.save(new Employee(2L, "ABC","PQR"));
        empRepository.save(new Employee(3L, "PXR","CHQ"));
    }

    }

Другие вопросы по теме