[RESOLVIDO] JSF - método de listagem sempre é executado no bean

E ai gente, tudo bom?
sou novo por aqui e to com um problema.
Tenho uma aplicação em JSF + Hibernate + Primefaces e estou com o seguinte problema:
Na minha página de listagem tenho a datatable listando os registros, e tenho alguns commandoButtons
para executar algumas ações como ir para a página de cadastro, ir para a página de edição e excluir.
Então quando quero executar alguma dessas ações eu seleciono uma linha na tabela e clico em algum desses botões.
Tudo funciona normalmente, porém eu percebi através do debug que qualquer ação que eu executar no bean, antes da ação
ser executada, o método que retorna a lista de registros para a datatable é executado.
Exemplo: tenho o método criar(), que leva para a página de cadastro. Quando clico no botão que chama o método criar(), antes a aplicação executa o getListaPerfis(), que é o método que retorna os registros para a datatable.
Quero saber se alguém pode me ajudar, pois não consigo entender porque ele faz isso.
segue ai abaixo o código do meu bean e da minha página:

PerfilBean.java

@ManagedBean
@RequestScoped
public class PerfilBean {
    private SGECPerfil perfil;
    private DataModel<SGECPerfil> listaPerfis;
    private String codString;
    
    public PerfilBean() {
        perfil = new SGECPerfil();
    }

    public String getCodString() {
        return codString;
    }

    public void setCodString(String codString) {
        this.codString = codString;
    }

    public DataModel<SGECPerfil> getListaPerfis() {
        if(listaPerfis == null){
            PerfilDAO pdao = new PerfilDAO();
            listaPerfis = new ListDataModel<SGECPerfil>(pdao.listarPagina());
        }
        return listaPerfis;
    }

    public void setListaPerfis(DataModel<SGECPerfil> listaPerfis) {
        this.listaPerfis = listaPerfis;
    }

    public SGECPerfil getPerfil() {
        return perfil;
    }

    public void setPerfil(SGECPerfil perfil) {
        this.perfil = perfil;
        FacesContext context = FacesContext.getCurrentInstance();
        context.getExternalContext().getSessionMap().remove("perfil");
        context.getExternalContext().getSessionMap().put("perfil", perfil);
    }
    
    public String listar(){
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().remove("perfil");
        return "perfilListagem";
    }
    
    public String listarModulos(){
        FacesContext context = FacesContext.getCurrentInstance();
        try {
            return "perfilModuloListagem";
        } catch (Exception e) {
            e.printStackTrace();
            context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Não Foi Possível Carregar os Módulos", null));
            return "perfilListagem";
        }
    }
    
    public String criar(){
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().remove("perfil");
        perfil = new SGECPerfil();
        return "perfilCadastro";
    }
    
    public String cadastrar(){
        FacesContext context = FacesContext.getCurrentInstance();
        try {
            SGECMembros logado = (SGECMembros) context.getExternalContext().getSessionMap().get("usuario");
            perfil.setSGECMembros(logado);//Usuário Membro Logado
            perfil.setPERFDataHoraCadastro(new Date(Calendar.getInstance().getTime().getTime()));
            PerfilDAO pdao = new PerfilDAO();
            pdao.cadastrarOuAtualizar(perfil);
            context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Perfil Cadastrado com Sucesso", null));
            return "perfilListagem";
        } catch (Exception e) {
            e.printStackTrace();
            context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Não Foi Possível Cadastrar o Perfil", null));
            return "perfilCadastro";
        }
    }
    
    public String editar(){
        FacesContext context = FacesContext.getCurrentInstance();
        try {
            context.getExternalContext().getSessionMap().remove("perfil");
            PerfilDAO pdao = new PerfilDAO();
            perfil = pdao.localizar(perfil.getPERFCodigo());
            codString = perfil.getPERFCodigo().toString();
            return "perfilEdicao";
        } catch (Exception e) {
            e.printStackTrace();
            context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Não Foi Possível Carregar as Informações do Perfil", null));
            return "perfilListagem";
        }
    }
    
    public String excluir(){
        FacesContext context = FacesContext.getCurrentInstance();
        try {
            context.getExternalContext().getSessionMap().remove("perfil");
            PerfilDAO pdao = new PerfilDAO();
            perfil = pdao.localizar(perfil.getPERFCodigo());
            pdao.excluir(perfil);
            context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Perfil Excluído com Sucesso", null));
            return "perfilListagem";
        } catch (Exception e) {
            e.printStackTrace();
            context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Não Foi Possível Excluir o Perfil", null));
            return "perfilListagem";
        }
    }
    
    public String atualizar(){
        FacesContext context = FacesContext.getCurrentInstance();
        try {
            PerfilDAO pdao = new PerfilDAO();
            perfil.setPERFCodigo(Integer.parseInt(context.getExternalContext().getRequestParameterMap().get("codPerfil")));
            SGECPerfil perfilTransicao = pdao.localizar(perfil.getPERFCodigo());
            perfilTransicao.setPERFNome(perfil.getPERFNome());
            perfil = perfilTransicao;
            pdao.cadastrarOuAtualizar(perfil);
            context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Perfil Atualizado com Sucesso", null));
            return "perfilListagem";
        } catch (Exception e) {
            e.printStackTrace();
            context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Não Foi Possível Atualizar o Perfil", null));
            return "perfilEdicao";
        }
    }

}

perfilListagem.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://java.sun.com/jsf/html"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:p="http://primefaces.prime.com.tr/ui"
      xmlns:f="http://java.sun.com/jsf/core">
    <ui:composition template="index.xhtml">
        <ui:define name="conteudo">
            <p:dataTable id="tabelaPerfis" var="perfil" value="#{perfilBean.listaPerfis}"
                         emptyMessage="Nenhum Registro Encontrado" paginator="true" rows="10"
                     paginatorTemplate="{FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink}"
                     paginatorPosition="bottom" selectionMode="single" selection="#{perfilBean.perfil}"
                     style="font-size: 11px;" update="codPerfil">

                     <f:facet name="header">
                         <table style="width: 92.5%; margin-top: 2.2%;">
                             <tr>
                                 <td style="text-align: left;"><h:outputText value="Lista de Perfis" style="font-size: 18px;"/></td>
                                 <td style="text-align: right;">
                                     <p:commandLink action="#{perfilBean.criar}" ajax="false" title="Cadastrar">
                                         <h:graphicImage url="images/8.png" style="border: none;" width="22" height="22"/>
                                     </p:commandLink>
                                     <p:commandLink action="#{perfilBean.editar}" ajax="false" title="Editar">
                                         <h:graphicImage url="images/2.png" style="border: none;" width="22" height="22"/>
                                     </p:commandLink>
                                     <p:commandLink onclick="confirmacao.show()" title="Excluir">
                                         <h:graphicImage url="images/9.png" style="border: none;" width="22" height="22"/>
                                     </p:commandLink>
                                     <p:commandLink action="#{perfilBean.listar}" immediate="true" ajax="false" title="Listar">
                                         <h:graphicImage url="images/page_preview-32.png" style="border: none;" width="22" height="22"/>
                                     </p:commandLink>
                                     <p:commandLink action="#{perfilBean.listarModulos}" immediate="true" ajax="false" title="Listar M&oacute;dulos">
                                         <h:graphicImage url="images/43.png" style="border: none;" width="22" height="22"/>
                                         <f:param id="codPerfil" name="codPerfil" value="#{perfilBean.codString}"/>
                                     </p:commandLink>
                                 </td>
                             </tr>
                         </table>
                     </f:facet>

                <p:column headerText="C&oacute;digo">
                     <h:outputText value="#{perfil.PERFCodigo}"/>
                 </p:column>

                <p:column headerText="Nome" filterBy="#{perfil.PERFNome}" filterMatchMode="contains">
                     <h:outputText value="#{perfil.PERFNome}"/>
                 </p:column>
            </p:dataTable>
            <p:confirmDialog header="Confirma&ccedil;&atilde;o de Exclus&atilde;o" widgetVar="confirmacao" severity="alert"
                message="Deseja realmente excluir este Perfil?" showEffect="bounce" hideEffect="explode">
                <p:commandButton value="Sim" update="tabelaPerfis,msgs" oncomplete="confirmacao.hide()" action="#{perfilBean.excluir}" ajax="false"/>
                <p:commandButton value="N&atilde;o" onclick="confirmacao.hide()" type="button"/>
            </p:confirmDialog>
        </ui:define>
    </ui:composition>
</html>

Só para constar, não uso faces-config, pois uso as annotations para os bean e tbm uso o redirecionamento implicito do JSF 2.0.
Agradeço a ajuda de vcs.

Olá,bem-vindo ao fórum.
Pelo que já li por ai,não dá pra prever quantas vezes o JSF tenta carregar a lista,a solução é tacar um
if(lista.size()==0) mesmo.

Então, mas eu ja fiz isso la no método de listagem. O problema é que mesmo que eu execute qualquer outro método,
antes ele executa o método da listagem. A aplicação funciona numa boa, mas isso faz ela ficar mais lenta, pois se eu
escolho ir para a página de cadastro ou então a de edição ou até mesmo excluir, antes o bean executa toda a listagem
novamente. Esse é o problema.

Vou mostrar como eu faço:

public String salvar(){
		String resultado="";
		try {
			resultado= mapaController.salvar(mapa,paginaSucesso,paginaErro);
			setMapas(new ArrayList&lt;MapaRisco&gt;());	
		}catch(Exception e){
			e.printStackTrace();
		}
		return resultado;
	}

Note que estou ‘limpando’ a listagem.

public List&lt;MapaRisco&gt; getMapas() {
		if(mapas.size()==0){
			mapas = mapaController.buscarMapas(new Long(4));
			total = mapas.size();
		}
		return mapas;
	}

Coloque process="@this" no botão criar para testar.

raf4ever, to vendo que vc limpa a listagem sim, mas eh pq ou não entendi o que vc quis dizer,
mas meu problema eh um pouco diferente. Eu já resolvi o problema de listar várias vezes, já que
por causa do ciclo de vida, o JSF executa o método a cada nova fase do ciclo. Isso eu já resolvi.
O problema agora eh que não entendo pq o bean executa o método de listagem num momento
que não era pra listar. Eu clico no botão excluir, ou criar(que leva pra pagina de cadastro),
ou editar(que leva pra pagina de edição) e ele vai e passa pelo método da listagem novamente.
É como se tivesse alguma coisa forçando o bean a sempre executar a listagem antes da ação dos
commandLinks.

E edudebom, testei sua solução, mas ainda não deu certo. Ficou na mesma

Agradeço a ajuda que vcs estão me dando ai, mas se puderem continuar vai ser ainda melhor!!
vlw mesmo.

e ai, será que mais alguém tem alguma idéia para me ajudar?
eu tava pensando aqui, será que é problema da datatable do primefaces?
como a datatable tem no value dela o método de listagem, será que toda
vez que o bean é chamado, ele processa a página toda e ai executa a listagem
da datatable de novo?
sei lá, é só uma idéia.
agradeço quem puder colaborar comigo.

gente, descobri que é isso mesmo. ao chamar uma ação no bean, a página toda tá sendo processada
e o método do value da datatable é executado novamente, antes da outra ação que foi chamada.
mas ainda não descobri como resolver isso, ou se isso tá acontecendo pq to fazendo alguma coisa errada.
agradeço qualquer ajuda ou dica.
vlw

[quote=ronnytds]gente, descobri que é isso mesmo. ao chamar uma ação no bean, a página toda tá sendo processada
e o método do value da datatable é executado novamente, antes da outra ação que foi chamada.
mas ainda não descobri como resolver isso, ou se isso tá acontecendo pq to fazendo alguma coisa errada.
agradeço qualquer ajuda ou dica.
vlw[/quote]
Acho que não há muito o que fazer com relação a isso.
Mas se a lista só será carregada novamente quando for nula,pq então isso é um problema?

é pq de qualquer forma ele executa uma listagem desnecessária, pois se eu cliquei
no botão de cadastrar, é para ele chamar o método criar() e depois ir para a página
de cadastro. mas do jeito que tá, ele passa pela listagem de forma desnecessária, pq
como o bean eh de request, ele é recriado com uma nova requisição, e consequentemente
a lista volta a ficar nula. isso nde fato não seria um problema, mas é que esse sistema é hospedado
nas nuvens, com o banco de dados tbm nas nuvens, então qualquer consulta desnecessária torna
o sistema mais lento.

Bom, mas eu tive uma idéia aqui e consegui resolver. eu coloquei um <f:param> dentro do commandLink,
e ai quando ele chega no bean, no método de listagem, eu recupero o parâmetro e vejo o seu valor.
de acordo com o valor do parâmetro a listagem é executada ou não.
dessa forma, toda ação executada por um dos commandLinks vai enviar o parâmetro informando que
a listagem não deve ser executada.

mas eu agradeço mesmo por toda a ajuda e atenção raf4ever!!
vlw mesmo
:smiley: