Olá desenvolvedores, neste tutorial trataremos algumas exceções no contexto do JSF – JavaServer Faces. A base de dados do nosso projeto traz duas tabelas que se relacionam entre si, isto é, implementam conceitos de cardinalidade. O relacionamento entre tabelas de um para muitos (1:N) significa que um usuário pode ter mais de um número de telefone, e dois ou mais números de telefones podem pertencer a um único usuário.
Em termos técnicos, o relacionamento do tipo um para muitos (1:N) é definido quando uma ocorrência de uma entidade pode se relacionar com várias ocorrências de outra entidade.
Assim, se não tratarmos o relacionamento que existe entre as duas entidades, quando tentarmos excluir um registro, cujo número de telefone foi cadastrado iremos violar a restrição de chave estrangeira. Porque neste caso a tabela de “telefones” perderia a sua referência, que aponta para a tabela pai “usuariopessoa”, e ambas apontam para o mesmo código do usuário na tabela. Entenda um pouco mais com o tutorial “CREATE TABLE E CARDINALIDADES”.
TRATANDO A EXCEÇÃO
A exceção a ser capturada e que identifica o problema referente a foreign key ou chave estrangeira é a ConstraintViolationException.
Tendo identificado a exceção que deverá ser capturada, no método deletarPorId() do DaoGeneric deveremos informar ao Java que a exceção será lançada para cima para ser capturada pelo Managed Bean. Fazemos isso adicionando um throws Exception na assinatura do método.
Automaticamente ao lançar a exceção para cima, o método remover() no Managed Bean irá exigir a adição dos blocos try/catch. Assim, todo o código de processamento responsável por deletar o objeto deverá ser envolvido pelo bloco try.
No bloco catch trataremos as exceções, como são vários os tipos de exceção que podem ocorrer, iremos tratá-las todas de forma genérica. Mas é preciso gerar uma mensagem para a exceção que identificamos, isto é, para a exceção de violação de chave estrangeira.
Desse modo, se a causa da exceção for uma ConstraintViolationException, enviaremos para o usuário uma mensagem específica para este erro.
A EXCEÇÃO DO LADO DO JSF
Quando um erro surge do lado do servidor o JSF se comporta de uma forma diferente, por esse motivo, deveremos “trabalhar” os componentes. Não queremos que ao deletar um objeto o formulário seja completamente recarregado, dessa forma deveremos separar o formulário de cadastro das funções de “Editar” e “Delete”.
Assim, deixaremos o formulário de cadastro dentro do seu próprio h:form, e implementaremos um novo h:form para a tabela dos usuários cadastrados com os botões de “Editar” e “Delete”. Adicione um identificador ao formulário da tabela de exibição dos dados cadastrados.
<h:form id=“formTable” >
Atribuiremos um identificador também ao objeto de mensagens dentro do formulário de cadastro.
<h:messages showDetail=“true” showSummary=“false” id=“msg” >
O próximo passo é renderizar por meio do atributo render do componente f:ajax do botão “Delete”, além da tabela, o formulário e o objeto de mensagem.
LÓGICA DE EXCLUSÃO DE OBJETO
Quando deletarmos um objeto, ele deverá ser removido do banco de dados e também da tabela. E quando salvarmos um objeto, ele deverá ser salvo na base de dados e adicionado a tabela.
Para isso removeremos a linha de código abaixo do método getList() do Managed Beam e a adicionaremos ao método init() que deverá ser anotado com o @PostConstruct. Assim, quando o ManegdBean for construído na memória ele executará o método apenas uma vez.
No UsuarioPessoa reescreva o método hashCode() and o equals(), apenas com o “id” para que o Java possa diferenciar os objetos. E para finalizar, no método salvar() adicionaremos o objeto a lista, e do mesmo modo, o removeremos no método remover().
EM POUCAS PALAVRAS
Para podermos trabalhar com as listas adicionando e removendo objetos é preciso implementar hashCode() and o equals(), para diferenciarmos o objeto pelo “id”. E no DaoGeneric lançamos a exceção para cima capturando essa exceção com o try/catch no Managed Bean. E adequarmos o comportamento do JSF ao tratamento de exceções.
Se a exceção for uma ConstraintViolationException, o objeto não será removido e uma mensagem será exibida para o usuário. Mas se não for, o objeto será removido da base de dados e da lista. E desse modo carregaremos estes dados do banco de dados apenas uma vez. No entanto, quando um objeto é deletado, apenas o “formulário” da tabela é carregado e um reload é realizado no objeto de mensagem.