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

JSF I - Problema ao remover item da lista logo após a inserção

Olá, Problema referente aos capitúlos 9 e 10 (CRUD com JSF)

Estou com um problema curioso ao tentar usar o Ajax para remover um autor da lista:

Quando preencho o formulário de autor, e clico em gravar, tudo ocorre OK, o novo autor é persistido. Mas se logo em seguida, tento remover esse mesmo autor que acabei de inserir, não acontece nada na página :/

Se dou refresh na página consigo remover ele normalmente, acredito que seja algum set no this.autor ou na lista de autores que não está ocorrendo de maneira correta

Essa é minha view:

<ui:define name="conteudo">
        <h:form>

            <h:messages id="messages" />

            <fieldset>
                <legend>Dados do Autor</legend>
                <h:panelGrid columns="2">
                    <h:outputText value="Nome" for="nome" />
                    <h:inputText id="nome" value="#{autorBean.autor.nome}"
                        required="True" requiredMessage="Nome é Obrigatório">
                        <f:ajax event="blur" render="messages" />
                    </h:inputText>
                </h:panelGrid>
                <h:panelGrid columns="2">
                    <h:outputText value="Email" for="email" />
                    <h:inputText id="email" value="#{autorBean.autor.email}">
                        <f:passThroughAttribute name="type" value="email" />
                    </h:inputText>
                </h:panelGrid>
                <h:commandButton value="Gravar" action="#{autorBean.gravar}">
                    <f:ajax execute="@form" render="@form tabelaAutores" />
                </h:commandButton>
                <br /> <br />
                <fieldset>
                    <legend>Lista de Autores</legend>
                    <h:dataTable id="tabelaAutores" value="#{autorBean.autores}"
                        var="autor">
                        <h:column>
                            <h:outputText value="#{autor.nome}" />
                        </h:column>
                        <h:column>
                            <h:commandButton id="removeAutor" value="X"
                                action="#{autorBean.remover(autor)}" immediate="true" />
                        </h:column>
                        <h:column>
                            <h:commandButton id="alteraAutor" value="Alterar"
                                action="#{autorBean.carregar(autor)}" />
                        </h:column>
                    </h:dataTable>
                </fieldset>
            </fieldset>
        </h:form>
    </ui:define>

Esse é meu MBean:

package br.com.alura.livraria.bean;

import java.util.List;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.persistence.EntityManager;

import br.com.alura.livraria.dao.AutorDAO;
import br.com.alura.livraria.model.Autor;
import br.com.alura.livraria.util.JpaUtil;

@ManagedBean
@ViewScoped
public class AutorBean {

    private EntityManager em = new JpaUtil().getEntityManager();
    private AutorDAO autorDAO = new AutorDAO(em);

    private Autor autor = new Autor();
    private List<Autor> autores;


    public Autor getAutor() {
        return autor;
    }

    public void setAutor(Autor autor) {
        this.autor = autor;
    }

    public List<Autor> getAutores() {
        this.autores = autorDAO.obterTodosAutores();
        return this.autores;
    }

    public void setAutores(List<Autor> autores) {
        this.autores = autores;
    }

    public void gravar() {

        if(this.autor.getId() == null){
            autorDAO.persist(autor);
            System.out.println("Gravou o Autor: " + autor.getNome());
        }else{
            autorDAO.merge(autor);
            System.out.println("Alterou o Autor: " + autor.getNome());
        }

        clear();

        //return "livro?faces-redirect=true";
    }

    public void remover(Autor autor){
        System.out.println("Removendo o autor: " + autor.getNome());
        autorDAO.remove(autor);
        System.out.println("Autor removido com sucesso.");

    }

    public void carregar(Autor autor){
        this.autor = autor;
    }

    public void carregarPorId(){

        Integer id = this.autor.getId();
        this.autor = autorDAO.obterAutorPorId(id);
        if (this.autor == null){
            this.autor = new Autor();
        }



    }

    public void clear(){
        autor = new Autor();
    }

}

Dúvida: Quando eu altero meu método Gravar, e coloco para o DAO refazer a pesquisa e preencher a lista de autores logo após persistir, tudo funciona ok.

Esse comportamento é o correto? logo após persistir o objeto eu preciso fazer uma nova consulta no banco de dados? E essa consulta deve ser dentro do meu método gravar? Pois penso que o JSF deveria cuidar disso automáticamente.

Estou fazendo algo errado?

Esse é meu método modificado no MBean do autor que faz "funcionar" :

public void gravar() {

        if(this.autor.getId() == null){
            autorDAO.persist(autor);
            System.out.println("Gravou o Autor: " + autor.getNome());
        }else{
            autorDAO.merge(autor);
            System.out.println("Alterou o Autor: " + autor.getNome());
        }

        this.autores = autorDAO.obterTodosAutores();
        clear();

        //return "livro?faces-redirect=true";
    }

Valeu!

2 respostas
solução!

Opa, com essa segunda versão funcionou, é isso? Pq realmente vc precisa recarregar a lista, para que ele possa montar a table baseado nela.

Obrigado pela resposta Alberto, Achei que o JPA ou JSF deveria fazer esse trabalho, e não ter que invocar o DAO para listar tudo denovo a cada nova modificação na entity.