Solucionado (ver solução)
Solucionado
(ver solução)
3
respostas

[Bug] this.service is null SPRING BOOT

Estou tendo um problema ao chamar um endpoint do meu controller na minha API. A seguinte exceção é lançada:

jakarta.servlet.ServletException: Request processing failed: java.lang.NullPointerException: Cannot invoke "com.porto.HealthLabApi.services.PessoaService.listarPessoas(org.springframework.data.domain.Pageable)" because "this.pessoaService" is null

A principio eu anotei corretamente a minha classe de @Service e @Repository. Segue minhas classes.

Controller:

@RestController
@RequestMapping("/pessoa")
public class PessoaController {

    @Autowired
    private ResponseHandler responseHandler;

    @Autowired
    private PessoaService pessoaService;

    @GetMapping
    private ResponseEntity<Object> listarPessoas(@PageableDefault(size = 10, sort = {"nome"}) Pageable paginacao){
        var pessoas = pessoaService.listarPessoas(paginacao).map(ResponsePessoa::new);

        return responseHandler.generateResponse("Consulta realizada com sucesso", true, HttpStatus.OK, pessoas);
    }

    @GetMapping("/{id}")
    private ResponseEntity<Object> detalharPessoa(@PathVariable Long id){
        var pessoa =  pessoaService.detalharPessoa(id);

        return responseHandler.generateResponse("Consulta realizada com sucesso", true, HttpStatus.OK, pessoa);
    }

    @PostMapping
    @Transactional
    private ResponseEntity<Object> cadastrarPessoa(@RequestBody @Valid RequestCadastrarPessoa dadosPessoa){
        var pessoaCriada = pessoaService.cadastrarPessoa(dadosPessoa);

        return responseHandler.generateResponse("Cadastrado com sucesso", true, HttpStatus.CREATED, pessoaCriada);
    }

    @PutMapping
    @Transactional
    private ResponseEntity<Object> editarPessoa(@RequestBody @Valid RequestEditarPessoa dadosPessoa){
        var pessoaEditada = pessoaService.editarPessoa(dadosPessoa);

        return responseHandler.generateResponse("Editado com sucesso", true, HttpStatus.OK, pessoaEditada);
    }

    @DeleteMapping("/{id}")
    @Transactional
    private ResponseEntity<Object> deletarPessoa(@PathVariable Long id){
        pessoaService.deletarPessoa(id);

        return responseHandler.generateResponse("Deletado com sucesso", true, HttpStatus.OK, null);
    }

}

Service:

@Service
public class PessoaService {
    
    @Autowired
    private PessoaRepository pessoaRepository;

    public Page<Pessoa> listarPessoas(Pageable paginacao) {
        return pessoaRepository.findAll(paginacao);
    }

    public Pessoa cadastrarPessoa(@Valid RequestCadastrarPessoa dadosPessoa) {
        var pessoa = new Pessoa(dadosPessoa);
        
        return pessoaRepository.save(pessoa);
    }

    public Pessoa detalharPessoa(Long id) {
        return pessoaRepository.getReferenceById(id);
    }

    public Pessoa editarPessoa(@Valid RequestEditarPessoa dadosPessoa) {
        var pessoa = pessoaRepository.getReferenceById(dadosPessoa.id());
        pessoa.atualizarInformacoes(dadosPessoa);

        return pessoaRepository.save(pessoa);
    }

    public void deletarPessoa(Long id) {
        var pessoa = pessoaRepository.getReferenceById(id);
        System.out.println(pessoa.getNome()); 
        pessoaRepository.delete(pessoa);
    }
}

Repository:

@Repository
public interface PessoaRepository extends JpaRepository<Pessoa, Long> {
    
    Page<Pessoa> findAll(Pageable paginacao);

}

Revirei o código e acabei não encontrando a causa de meu service estar nulo :(

3 respostas

O erro que você está enfrentando indica que this.pessoaService está nulo quando você chama o método listarPessoas no seu controller.

Uma possível causa para isso é que a injeção de dependência do Spring não está funcionando corretamente para o seu PessoaService.

Uma solução que você pode tentar é adicionar a anotação @Service na classe PessoaService para garantir que o Spring reconheça e gerencie corretamente essa classe como um componente do seu aplicativo. Além disso, verifique se você tem a configuração adequada para a varredura de componentes no seu projeto Spring.

Outra possível causa é que você esteja usando uma versão antiga do Spring que não suporta a injeção de dependência por campo em classes não gerenciadas pelo Spring. Nesse caso, você pode tentar usar a injeção de dependência por construtor em vez da injeção por campo. Por exemplo, você pode modificar o seu controller da seguinte forma:

@RestController
@RequestMapping("/pessoa")
public class PessoaController {

    private final ResponseHandler responseHandler;
    private final PessoaService pessoaService;

    @Autowired
    public PessoaController(ResponseHandler responseHandler, PessoaService pessoaService) {
        this.responseHandler = responseHandler;
        this.pessoaService = pessoaService;
    }

    // Restante do código...
}

Essa modificação permite que as dependências ResponseHandler e PessoaService sejam injetadas por meio do construtor, garantindo que elas não estejam nulas quando você chama os métodos do seu controller.

Obrigado pela resposta. Infelizmente não funcionou, lançou a mesma exceção :(

PS: estou usando o Spring na versão 3.0.11, acredito que o @Autowired funcione corretamente.

solução!

Testei apagar as classes de controller, service e repository e colar o código por cima de novo e deu certo. Não sei o porquê, mas acredito que algum metadado de IDE ou sei lá o que ficou incorreto. O código tá literalmente o mesmo e funciona agora! :D