4
respostas

Bug de edição formulário autor

Olá caros,

Identifiquei o que acredito que seja um bug na aplicação. No formulário de autores, eu clico para editar algum autor, e apago o email do mesmo, depois clico em gravar. Como esperado o formulário cai na validação e exibe msg de erro, "Campo email é obrigatório". Depois disso se clico em autro autor para editar , somente o campo email é preenchido o campo nome passa a não mudar mais continuando com o nome do autor que tentei gravar ateriormente. Ainda não consegui identificar a causa deste problema.

autor.xhtml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://xmlns.jcp.org/jsf/html"
    xmlns:f="http://xmlns.jcp.org/jsf/core"
    xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
    xmlns:p="http://primefaces.org/ui">

<ui:composition template="_template.xhtml">

    <f:metadata>
        <f:viewParam name="autorId" value="#{autorBean.autor.id}" />
        <f:viewAction action="#{autorBean.carregarAutorPelaId}"
            if="#{param.autorId != null}" />
    </f:metadata>

    <ui:define name="titulo">
        <p:outputPanel>Novo Livro</p:outputPanel>
    </ui:define>
    <ui:define name="conteudo">
        <p:messages id="mensagens" />
        <h:form id="cadastroautor">
            <p:fieldset legend="Dados do Autor">
                <h:panelGrid columns="2">
                    <p:outputLabel value="Nome:" for="nome" />
                    <p:inputText id="nome" value="#{autorBean.autor.nome}"
                        required="true" requiredMessage="Nome do autor é obrigatório"
                        validatorMessage="Deve ter no mínimo 5 caracteres!">
                        <f:validateLength minimum="5" />
                    </p:inputText>

                    <p:outputLabel value="Email" for="email" />
                    <p:inputText id="email" value="#{autorBean.autor.email}"
                        validatorMessage="Email Inválido!" required="true">
                        <f:validateRegex pattern=".+@.+"
                            validatorMessage="Email Inválido!" />
                    </p:inputText>
                    <p:commandButton value="Gravar" actionListener="#{autorBean.gravar}"
                    validateClient="true"    update="@form :mensagens :listaautores:tabelaAutores" process="@form" />
                </h:panelGrid>
            </p:fieldset>
        </h:form>
        <h:form id="listaautores">

            <p:dataList id="tabelaAutores" value="#{autorBean.autores}"
                var="autor">
                <f:facet name="header">
            Autores
        </f:facet>
                <p:commandLink value="Editar" id="editar"
                    styleClass="ui-icon ui-icon-pencil"
                    style="float:left;margin-right:10px" update="@form :cadastroautor">
                    <f:setPropertyActionListener target="#{autorBean.autor}"
                        value="#{autor}" />
                </p:commandLink>

                <p:commandLink value="Remover" action="#{autorBean.remover(autor)}"
                    id="remover" styleClass="ui-icon ui-icon-trash"
                    style="float:left;margin-right:10px" process="remover"
                    update="@form :listaautores:tabelaAutores :mensagens">
                </p:commandLink>
        #{autor.nome}, #{autor.email}
    </p:dataList>


        </h:form>
    </ui:define>
    <ui:define name="titulo_rodape">Autor</ui:define>
</ui:composition>
</html>

AutorBean

package br.com.caelum.livraria.bean;

import java.util.List;

import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.persistence.RollbackException;
import br.com.caelum.livraria.dao.DAO;
import br.com.caelum.livraria.modelo.Autor;
import br.com.caelum.livraria.util.RedirectView;

@ManagedBean
@ViewScoped
public class AutorBean {

    private Autor autor = new Autor();


    public Autor getAutor() {
        System.out.println("Get="+this.autor.getNome());
        return this.autor;
    }

    public void setAutor(Autor autor) {    
        this.autor =  new Autor();
        this.autor = autor;
        System.out.println("Set="+this.autor.getNome());
    }

    public RedirectView gravar() {
        System.out.println("Gravando autor " + this.autor.getNome());

        if (this.autor.getId() == null) {
            new DAO<Autor>(Autor.class).adiciona(this.autor);
        } else {
            new DAO<Autor>(Autor.class).atualiza(this.autor);
        }

        this.autor = new Autor();

        return new RedirectView("livro");
    }

    public void remover(Autor autor) {
        try {
            new DAO<Autor>(Autor.class).remove(autor);
        } catch (RollbackException e) {
            FacesContext.getCurrentInstance().addMessage("autor", new FacesMessage(
                    "O autor " + autor.getNome() + " não pode ser excluido pois está associado a algum livro!"));
            return;
        }

    }

    public void carregarAutorPelaId() {

        Integer id = this.autor.getId();
        this.autor = new DAO<Autor>(Autor.class).buscaPorId(id);
        if (this.autor == null) {
            this.autor = new Autor();
        }
    }

    public List<Autor> getAutores() {
        return new DAO<Autor>(Autor.class).listaTodos();
    }

}
4 respostas

Fala Fabio, testei aqui na minha máquina e tanto com o SetPropertyActionListener quanto com um método para alterar deu o mesmo problema...

Acredito que seja alguma coisa referente a validação porque qdo tiramos a validação e clicamos em outro autor para alterar ele funciona normalmente...

O que acredito que esteja acontecendo é que durante a validação o componente nome perde a referência na árvore de componentes... mas eu preciso dar mais uma olhada aqui com calma para ter certeza.

Olá Samir,

Então minha suspeita era correta, realmente isso é um bug do JSF e não um erro de desenvolvimento?

Alguma conclusão ?

Oi Fábio, desculpe a demora...

Mesmo utilizando o "immediate=true" no botão de alterar, o resultado é o mesmo... O Immediate seria responsável por pular a fase de validação e executar os métodos na segunda fase do ciclo de vida. Mesmo assim o erro persistiu. Acredito que realmente seja um bug do JSF.