-1

Спринг выдаёт NullPointerException в запросе, обновляющем сразу две таблицы. GET- запрос с аналогичными данными, но использующий только один сервис, полностью рабочий. Можете подсказать, что не так, пожалуйста?

Классы сервисов:


import com.example.uralsibtest.enums.Position;
import com.example.uralsibtest.exceptions.DepartmentNotFoundException;
import com.example.uralsibtest.exceptions.EmployeeNotFoundException;
import com.example.uralsibtest.exceptions.PositionNotFoundException;
import com.example.uralsibtest.model.Employee;
import com.example.uralsibtest.repository.DepartmentRepository;
import com.example.uralsibtest.repository.EmployeeRepository;
import org.json.simple.parser.ParseException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service public class EmployeeServiceImpl implements EmployeeService {

@Autowired
private EmployeeRepository employeeRepository;

@Autowired
private DepartmentRepository departmentRepository;

@Override
public Employee updateEmployeePosition(Integer employeeId, String newPosition)
        throws EmployeeNotFoundException, PositionNotFoundException, DepartmentNotFoundException, ParseException {
    Employee employee = (Employee) employeeRepository.findById(employeeId)
            .orElseThrow(() -> new EmployeeNotFoundException(employeeId));

    String strNewPosition = JsonParser.getJsonValue(newPosition, "newPosition");

    if (strNewPosition.equals(Position.CONSULTANT.getPositionValue()) ||
            strNewPosition.equals(Position.MIDDLE_DEVELOPER.getPositionValue()) ||
            strNewPosition.equals(Position.SENIOR_DEVELOPER.getPositionValue()) || 
    strNewPosition.equals(Position.JUNIOR_DEVELOPER.getPositionValue())) {
        DepartmentServiceImpl departmentService = new DepartmentServiceImpl();

        if (!departmentService.returnDepartmentByPosition(employee.getPosition())
                .equals(departmentService.returnDepartmentByPosition(strNewPosition))) {
            Integer departmentId = departmentService.returnDepartmentByPosition(strNewPosition);

            //this
            if (departmentService.updateEmployeesCount(departmentId)) {
                //
                return employee;
            } else {
                throw new DepartmentNotFoundException(departmentId);
            }
        }

        employee.setPosition(strNewPosition);
        employeeRepository.save(employee);
    } else {
        throw new PositionNotFoundException(newPosition);
    }
    return null;
}

public Employee updateEmployeeName(Integer employeeId, String newName) throws
        EmployeeNotFoundException{
    Employee employee = (Employee) employeeRepository.findById(employeeId)
            .orElseThrow(() -> new EmployeeNotFoundException(employeeId));
    employee.setName(newName);
    employeeRepository.save(employee);
    return employee;
}

public Employee createEmployee(Employee employee) throws PositionNotFoundException{
    if (employee.getPosition().equals(Position.CONSULTANT.getPositionValue()) 
            || employee.getPosition().equals(Position.MIDDLE_DEVELOPER.getPositionValue()) ||
    employee.getPosition().equals(Position.JUNIOR_DEVELOPER.getPositionValue()) ||
    employee.getPosition().equals(Position.SENIOR_DEVELOPER.getPositionValue())) {
        employeeRepository.save(employee);
        return employee;
    } else {
        throw new PositionNotFoundException(employee.getPosition());
    }
}

public Employee getEmployeeById(Integer employeeId) throws EmployeeNotFoundException{
    return (Employee) employeeRepository.findById(employeeId)
            .orElseThrow(() -> new EmployeeNotFoundException(employeeId));

}

}


import com.example.uralsibtest.enums.Position;
import com.example.uralsibtest.exceptions.DepartmentNotFoundException;
import com.example.uralsibtest.exceptions.PositionNotFoundException;
import com.example.uralsibtest.model.Department;
import com.example.uralsibtest.repository.DepartmentRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class DepartmentServiceImpl implements DepartmentService {

    @Autowired
    DepartmentRepository departmentRepository;

    public Integer returnDepartmentByPosition(String position) throws PositionNotFoundException {
        if (position.equals(Position.SENIOR_DEVELOPER.getPositionValue()) ||
                position.equals(Position.JUNIOR_DEVELOPER.getPositionValue()) ||
                position.equals(Position.MIDDLE_DEVELOPER.getPositionValue())) {
            return 1;
        } else if (position.equals(Position.CONSULTANT.getPositionValue())){
            return 2;
        } else {
            throw new PositionNotFoundException(position);

        }
    }

    public Boolean updateEmployeesCount(Integer id) throws DepartmentNotFoundException {
        Department department1 = findDepartmentById(id);
        Department department2 = findDepartmentById(id == 1 ? 2 : 1);

        System.out.println(department1.getEmployeesCount());

        department1.setEmployeesCount(department1.getEmployeesCount() - 1);
        department2.setEmployeesCount(department2.getEmployeesCount() + 1);
        departmentRepository.save(department1);
        departmentRepository.save(department2);
        return true;
    }

    public List findAllDepartments() {
        return departmentRepository.findAll();
    }

    public Department findDepartmentById(Integer id) throws DepartmentNotFoundException {
//        System.out.println(departmentRepository == null); false
        return (Department) departmentRepository.findById(id)
                .orElseThrow(() -> new DepartmentNotFoundException(id));
    }
}

Классы контроллеров:


import com.example.uralsibtest.exceptions.DepartmentNotFoundException;
import com.example.uralsibtest.model.Department;
import com.example.uralsibtest.service.DepartmentServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController public class DepartmentController {

@Autowired
DepartmentServiceImpl departmentServiceImpl;

@PutMapping("/department/{id}/update/supervisor")
public ResponseEntity updateDepartmentSupervisor(@PathVariable (value = "id") Integer departmentId) {
    return null;
}

@PutMapping("/internal/department/{id}/employees-count/update")
public Boolean updateEmployeesCount(@PathVariable(value = "id") Integer id) throws DepartmentNotFoundException {
    return departmentServiceImpl.updateEmployeesCount(id);
}

@GetMapping("/departments")
public List findAllDepartments() {
    return departmentServiceImpl.findAllDepartments();
}

@GetMapping("department/{id}")
public Department returnDepartmentById(@PathVariable(value = "id") Integer id) throws DepartmentNotFoundException{
    return departmentServiceImpl.findDepartmentById(id);
}

}

import com.example.uralsibtest.exceptions.DepartmentNotFoundException;
import com.example.uralsibtest.exceptions.EmployeeNotFoundException;
import com.example.uralsibtest.exceptions.PositionNotFoundException;
import com.example.uralsibtest.model.Employee;
import com.example.uralsibtest.service.EmployeeServiceImpl;
import org.json.simple.parser.ParseException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@RestController
public class EmployeeController{

    @Autowired
    EmployeeServiceImpl employeeService;

    @GetMapping("employee/{id}")
    public Employee getEmployeeById(@PathVariable(value = "id")Integer employeeId) throws EmployeeNotFoundException{
        return employeeService.getEmployeeById(employeeId);

    }

    @PostMapping("/employee/create")
    public Employee createEmployee( @RequestBody Employee employee) throws PositionNotFoundException{
        return employeeService.createEmployee(employee);
    }

    @PutMapping("/employee/{id}/update/name")
    public Employee updateEmployeeName(@PathVariable(value = "id") Integer employeeId,
                                       @RequestBody String newName) throws
            EmployeeNotFoundException{
        return employeeService.updateEmployeeName(employeeId, newName);
    }

    @PutMapping("/employee/{id}/update/position")
    public Employee updateEmployeePosition(@PathVariable(value = "id") Integer employeeId,
                                           @RequestBody String newPosition) throws EmployeeNotFoundException,
            PositionNotFoundException, DepartmentNotFoundException, ParseException {
        return employeeService.updateEmployeePosition(employeeId, newPosition);
    }
}

Логи самой ошибки:

Hibernate: 
    select
        e1_0.id,
        e1_0.address,
        e1_0.department,
        e1_0.employment_date,
        e1_0.name,
        e1_0.phone,
        e1_0.position 
    from
        employee e1_0 
    where
        e1_0.id=?
2023-06-25T03:47:59.739+03:00 ERROR 11288 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: java.lang.NullPointerException: Cannot invoke "com.example.uralsibtest.repository.DepartmentRepository.findById(Object)" because "this.departmentRepository" is null] with root cause

java.lang.NullPointerException: Cannot invoke "com.example.uralsibtest.repository.DepartmentRepository.findById(Object)" because "this.departmentRepository" is null at com.example.uralsibtest.service.DepartmentServiceImpl.findDepartmentById(DepartmentServiceImpl.java:51) ~[classes/:na] at com.example.uralsibtest.service.DepartmentServiceImpl.updateEmployeesCount(DepartmentServiceImpl.java:33) ~[classes/:na] at com.example.uralsibtest.service.EmployeeServiceImpl.updateEmployeePosition(EmployeeServiceImpl.java:42) ~[classes/:na] at com.example.uralsibtest.controller.EmployeeController.updateEmployeePosition(EmployeeController.java:40) ~[classes/:na] at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104) ~[na:na] at java.base/java.lang.reflect.Method.invoke(Method.java:578) ~[na:na] at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:207) ~[spring-web-6.0.9.jar:6.0.9] at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:152) ~[spring-web-6.0.9.jar:6.0.9] at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118) ~[spring-webmvc-6.0.9.jar:6.0.9] at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:884) ~[spring-webmvc-6.0.9.jar:6.0.9] at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:797) ~[spring-webmvc-6.0.9.jar:6.0.9] at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-6.0.9.jar:6.0.9] at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1081) ~[spring-webmvc-6.0.9.jar:6.0.9] at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:974) ~[spring-webmvc-6.0.9.jar:6.0.9] at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1011) ~[spring-webmvc-6.0.9.jar:6.0.9] at org.springframework.web.servlet.FrameworkServlet.doPut(FrameworkServlet.java:925) ~[spring-webmvc-6.0.9.jar:6.0.9] at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:593) ~[tomcat-embed-core-10.1.8.jar:6.0] at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885) ~[spring-webmvc-6.0.9.jar:6.0.9] at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658) ~[tomcat-embed-core-10.1.8.jar:6.0] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:205) ~[tomcat-embed-core-10.1.8.jar:10.1.8] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.8.jar:10.1.8] at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) ~[tomcat-embed-websocket-10.1.8.jar:10.1.8] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.8.jar:10.1.8] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.8.jar:10.1.8] at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-6.0.9.jar:6.0.9] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.9.jar:6.0.9] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.8.jar:10.1.8] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.8.jar:10.1.8] at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-6.0.9.jar:6.0.9] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.9.jar:6.0.9] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.8.jar:10.1.8] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.8.jar:10.1.8] at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-6.0.9.jar:6.0.9] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.9.jar:6.0.9] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.8.jar:10.1.8] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.8.jar:10.1.8] at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:166) ~[tomcat-embed-core-10.1.8.jar:10.1.8] at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) ~[tomcat-embed-core-10.1.8.jar:10.1.8] at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482) ~[tomcat-embed-core-10.1.8.jar:10.1.8] at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115) ~[tomcat-embed-core-10.1.8.jar:10.1.8] at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) ~[tomcat-embed-core-10.1.8.jar:10.1.8] at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) ~[tomcat-embed-core-10.1.8.jar:10.1.8] at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:341) ~[tomcat-embed-core-10.1.8.jar:10.1.8] at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:390) ~[tomcat-embed-core-10.1.8.jar:10.1.8] at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) ~[tomcat-embed-core-10.1.8.jar:10.1.8] at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:894) ~[tomcat-embed-core-10.1.8.jar:10.1.8] at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1741) ~[tomcat-embed-core-10.1.8.jar:10.1.8] at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) ~[tomcat-embed-core-10.1.8.jar:10.1.8] at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[tomcat-embed-core-10.1.8.jar:10.1.8] at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-10.1.8.jar:10.1.8] at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-10.1.8.jar:10.1.8] at java.base/java.lang.Thread.run(Thread.java:1623) ~[na:na]

Roman C
  • 9,043
  • 4
  • 20
  • 28

1 Answers1

1

В логах же написано

java.lang.NullPointerException: Cannot invoke "com.example.uralsibtest.repository.DepartmentRepository.findById(Object)" because "this.departmentRepository" is null at com.example.uralsibtest.service.DepartmentServiceImpl.findDepartmentById(DepartmentServiceImpl.java:51) ~[classes/:na] at com.example.uralsibtest.service.DepartmentServiceImpl.updateEmployeesCount(DepartmentServiceImpl.java:33) ~[classes/:na] at com.example.uralsibtest.service.EmployeeServiceImpl.updateEmployeePosition(EmployeeServiceImpl.java:42) ~[classes/:na]

То есть вы зачем-то создаёте экземпляр сервиса DepartmentServiceImpl локально при вызове метода EmployeeServiceImpl::updateEmployeePosition, НЕ используя механизмы Spring и НЕ передавая экземпляр репозитория при помощи конструктора, соответственно в этом экземпляре значение репозитория departmentRepository остаётся null-овым.

Если у вас есть зависимость на другой сервис, имеет смысл вынести эту переменную на уровень класса и сделать её Autowired полем, убрав создание нового экземпляра при помощи new DepartmentService():

public class EmployeeServiceImpl implements EmployeeService {
@Autowired
private DepartmentService departmentService;

// ...

@Override
public Employee updateEmployeePosition(Integer employeeId, String newPosition)
        throws EmployeeNotFoundException, PositionNotFoundException, DepartmentNotFoundException, ParseException {
    Employee employee = (Employee) employeeRepository.findById(employeeId)
            .orElseThrow(() -> new EmployeeNotFoundException(employeeId));

    String strNewPosition = JsonParser.getJsonValue(newPosition, "newPosition");

    if (strNewPosition.equals(Position.CONSULTANT.getPositionValue()) ||
            strNewPosition.equals(Position.MIDDLE_DEVELOPER.getPositionValue()) ||
            strNewPosition.equals(Position.SENIOR_DEVELOPER.getPositionValue()) || 
    strNewPosition.equals(Position.JUNIOR_DEVELOPER.getPositionValue())) {

// УБРАТЬ DepartmentServiceImpl departmentService = new DepartmentServiceImpl();

        if (!departmentService.returnDepartmentByPosition(employee.getPosition())
                .equals(departmentService.returnDepartmentByPosition(strNewPosition))) {
            Integer departmentId = departmentService.returnDepartmentByPosition(strNewPosition);
    // ...

}

Nowhere Man
  • 15,995
  • 33
  • 19
  • 29