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

Como redirecionar depois de deletar

É o seguinte, tenho uma ficha que possui vários produtos.

A função para alterar fica assim:

@Put("/produtos/{produto.id}")
    public void altera(@Valid Produto produto){
        validator.onErrorRedirectTo(this).edita(produto.getId());
        produtoDao.atualiza(produto);
        result.redirectTo(FichaController.class).incluir(produto.getFicha().getId());
    }

Ao realizar a atualização ele retorna para a ficha correspondente do produto. (OK)

Mas e para deletar? Como fazer se o produto não existe mais, e consequentemente o id da ficha referente a ele também não. Como fazer esse redirecionamento ?

17 respostas

Fala ai, de boa ?

É bem comum retornarmos para uma lista ou algo mais generico avisando que foi removido.

Isso eu sei fazer né.

Vou tentar explicar de novo.

Tenho uma Ficha que possui vários produtos.

Tem uma página que exibe os produtos de cada lista.

Esses produtos podem ser modificados e deletados.

Quando a escolha é para modificar, é jogado para página de alteração do produto. Ele é alterado e depois eu faço o retorno para a lista referente a ele.

result.redirectTo(FichaController.class).incluir(produto.getFicha().getId());

Só que eu não to conseguindo pensar em uma lógica para redirecionar depois que o produto for deletado.

Até porque o produto não existirá mais.

Acho que faz sentido voltar para a ficha então, que é um ponto antes no seu fluxo.

Como se o produto foi excluído e eu utilizava o idFicha que estava nele? Conforme o código abaixo.

result.redirectTo(FichaController.class).incluir(produto.getFicha().getId());

Então, você deletou ele do banco, mas durante aquele ponto de código você ainda tem ele na memória, com isso você tem todos os atributos

E como eu busco ele na memória?

result.use(Results.logic()).redirectTo(FichaController.class).incluir(produto.getFicha().getId());

@Delete("/produtos/{produto.id}")
    public void deleta(@Valid Produto produto){
        produtoDao.deleta(produto);
        result.redirectTo(FichaController.class).incluir(produto.getFicha().getId());
    }

Algo similar a isto

Se você subir o post vai ver que eu já havia postado esse código:

result.redirectTo(FichaController.class).incluir(produto.getFicha().getId());

Gera este erro que, parece acontecer por não ter o id da ficha do produto.

https://gist.github.com/anonymous/ec9cde532220d7e3e2292cb92d70692b

Nessa linha

Hibernate: delete from Produto where id=?

Pelo erro, parece que o produto está nulo.

Consegue confirmar se ele tá chegando ?

Acho que você não está entendendo.

A remoção está funcionando normalmente, o problema está na forma de redirecionar.

Quando eu deleto o produto e redireciono para lista funciona certinho.

result.redirectTo(FichaController.class).lista();

Porém quando eu tento redirecionar para a ficha referente ai produto deletado não vai. Porque o redirect está tentando pegar o idFicha do produto que já foi deletado.

result.redirectTo(FichaController.class).incluir(produto.getFicha().getId());

Este é o meu problema.

Oi Thiago, tudo bem?

O que pode estar acontecendo é que algo como entityManager.remove(produto), o objeto produto ficaria marcado como removed, nao sendo mais gerenciado pela JPA. daí o hibernate não busca mais a ficha no banco (que provavelmente já nao estava preenchida dentro do produto).

Talvez você possa primeiro carregar a ficha e depois chamar o remove. Algo como:

Ficha ficha = produto.getFicha();
em.remove(produto);
result.redirectTo(FichaController.class).incluir(ficha.getId());

Testa aí?

Qualquer coisa posta o método completo do seu remover do Controller aqui pra gente analisar?

Abraço!

A ideia é exatamente essa, porém desse jeito também não funciona.

Meu controller:

    @Remove
    public void remove(Produto produto) {
        Ficha ficha = produto.getFicha();
        produtoDao.remove(produto);
        result.redirectTo(FichaController.class).incluir(ficha.getId());
    }

Apaga o produto mas ao redirecionar gera esse erro:

https://gist.github.com/anonymous/108ede4e98bf74c4553d44c6ba5366c7

Tentei assim também, mas não deu:

    @Remove
    public void remove(Produto produto) {
        int fichaId = produto.getFicha().getId();
        produtoDao.remove(produto);
        result.redirectTo(FichaController.class).incluir(fichaId);
    }

Opa Thiago!

Quais dados então vindo na requisição? Só o id do produto?

Se for, antes você vai ter que fazer um find no produto então...

produto = em.find(Produto.class, produto.getId());

Como está o código de remoção no seu dao?

Outra opção seria mandar o id da ficha na requisição.

No meu Dao está assim:

    public void remove(Produto produto) {
        manager.getTransaction().begin();
        produto = busca(produto);
        manager.remove(produto);
        manager.getTransaction().commit();
    }
    public Produto busca(Produto produto) {
        return manager.find(Produto.class, produto.getId());
    }
solução!

Uma opção seria fazer:

Produto p = dao.busca(produto);
Ficha f = p.getFicha();
dao.remove(p);
result.redirectTo(FichaController.class).incluir(fichaId);

Tenta aí?

Deu certo. Mas eu não entendi o porque do outro jeito não ter funcionado. Se os dados do modelo já tinha chegado no controller porque tive que fazer outra busca?

Oi Thiago, o porquê de não ter funcionado da primeira forma que você fez?

Como os dados estavam vindo da requisição?