I cannot show an exception when I set a value that my foreign key does not exist in JSON when I will persist

Asked

Viewed 36 times

-2

I own a Lancamento class that inside it I have 2 foreign keys that would be pessoa_codigo e categoria_codigo, I managed to create an exception when I report a non-existent value for any of these foreign keys! In this case, I’m only able to capture the error in a column that would be: categoria_code already the column personal code* I can’t, because it brings me an exception that I don’t know how to solve.

Example of my JSON when trying to persist the lancing object

   { "descricao": "Lanche",
    "dataVencimento": "2017-06-10",
    "dataPagamento": null,
    "valor": 10.20,
    "observacao": null,
    "tipoLancamento": "DESPESA",
    "categoria": {
        "codigo": 100
    },
    "pessoa": {
        "codigo": 10
        }
    }
   

Note that in the code of the category I put the 100 that in the case does not exist this category in the bank, but I managed to capture my exception:

 {
    "msgUsuario": "Operação não permitida",
    "msgDesenvolvedor": "SQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails (`algamoneyapi`.`lancamento`, CONSTRAINT `lancamento_ibfk_1` FOREIGN KEY (`codigo_categoria`) REFERENCES `categoria` (`codigo`))"
}

Now I will put for example a value in the code on the person who does not exist. and I have this Error:

"timestamp": "2021-04-27T00:16:31.897+00:00",
"status": 500,
"error": "Internal Server Error",
"trace": "java.util.NoSuchElementException: No value present\n\tat java.base/java.util.Optional.get(Optional.java:141)\n\tat com.example.algamoney.service.LancamentoService.salva(LancamentoService.java:27)\n\tat com.example.algamoney.resource.LancamentoResource.criar(LancamentoResource.java:63)\n\tat java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\n\tat java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64)\n\tat java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\n\tat java.base/java.lang.reflect.Method.invoke(Method.java:564)\n\tat org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:197)\n\tat org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:141)\n\tat org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle
  "message": "No value present",
    "path": "/lancamentos"

My Service class

  @Service
public class LancamentoService {

    @Autowired
    private PessoaRepository pessoaRepository;

    @Autowired
    private LancamentoRepository lancamentoRepository;

    public Lancamento salva(Lancamento lancamento) {

        Optional<Pessoa> pessoaRecuperada = pessoaRepository.findById(lancamento.getPessoa().getCodigo());
        if (pessoaRecuperada == null || pessoaRecuperada.get().isAtivo() == false) {
            
            throw new PessoaInexistenteOuInativaException();
        }
        return lancamentoRepository.save(lancamento);
    }

2 answers

1


Good night. The problem is that you are calling the Optional get without testing if it is empty. You can do it this way:


@Service
public class LancamentoService {

    @Autowired
    private PessoaRepository pessoaRepository;

    @Autowired
    private LancamentoRepository lancamentoRepository;

    public Lancamento salva(Lancamento lancamento) {

        Pessoa pessoaRecuperada = pessoaRepository
          .findById(lancamento.getPessoa().getCodigo())
          .orElseThrow(()-> new PessoaInexistenteOuInativaException());

        if (!pessoaRecuperada.isAtivo()) {
            throw new PessoaInexistenteOuInativaException();
        }

        return lancamentoRepository.save(lancamento);
    }
}

Another way would be:


@Service
public class LancamentoService {

    @Autowired
    private PessoaRepository pessoaRepository;

    @Autowired
    private LancamentoRepository lancamentoRepository;

    public Lancamento salva(Lancamento lancamento) {

        Optional<Pessoa> pessoaRecuperada = pessoaRepository
          .findById(lancamento.getPessoa().getCodigo());

        if (pessoaRecuperada.isEmpty() || pessoaRecuperada.get().isAtivo() == false) {
            throw new PessoaInexistenteOuInativaException();
        }

        return lancamentoRepository.save(lancamento);
    }
}

The Optional.isEmpty() method is available from Java 11. For java 8 you have to use the Optional.isPresent negative()

  • Ball show worked! , captured the error message of the exception. Now I will try to see how to capture my message Sqlintegrityconstraintviolationexception.

0

Good evening Dayson, tries to accomplish this way, so he will have the exception pro controller and the controller vc can treat or send the log or send the exception with the throw to anyone who order or simply deal with the controller.

public Lancamento salva(Lancamento lancamento) throws PessoaInexistenteOuInativaException{

        Optional<Pessoa> pessoaRecuperada = pessoaRepository.findById(lancamento.getPessoa().getCodigo());
        if (pessoaRecuperada == null || pessoaRecuperada.get().isAtivo() == false) {
            
            throw new PessoaInexistenteOuInativaException();
        }
        return lancamentoRepository.save(lancamento);
    }

Browser other questions tagged

You are not signed in. Login or sign up in order to post.