Estado do Managed Bean no request

Olá pessoal!

Eu tenho um jsf com grid e um form, e renderizo-os conforme o que o usuário quiser, pesquisar ou dar manutenção nos dados.
Depois de muito quebrar a cabeça descobri que para nao instanciar novamente (e perder meus objetos) o meu MB eu teria q colocá-lo no escopo da sessão ou usar o t:saveState do Tomahawk.
O que eu gostaria de saber é, isso é um pau do jsf ou é erro (meu) de conceito??
Eu nao queria usar + 1 framework (Tomahawk) no meu projeto, entao utilizar todas os MB na session fica lento? Perde-se algo?

Desde já agradeço as respostas!

Cara…
Não é aconselhável você colocar todos os seus managedBean em escopo session pq eles ficam armazenados na sessão do usuário do seu servidor de aplicação. Depois de um tempo de utilização, além de ficar lento, você pode acabar com um “PermGen Space”, acabando com a memória do seu servidor de aplicação, tendo que reiniciá-lo constantemente.

Só use o escopo session com for realmente necessário senão pode acabar com sérios problemas de performance da sua aplicação.

Existe outro jeito sem utilizar o Tomahawk?

Sim, é possível fazer funcionar sem o componente do Tomahawk e sem necessidade de colocar o managed bean na session.
Simplesmente faça teu método acessor da lista de resultados sempre carregar os mesmos valores a cada request, algo como:

public List<Produto> getProdutos() { if (this.produtos == null) this.produtos = ProdutosRepositorios.getProdutosPelaDescricao(this.descricao); return this.produtos; }

Observe que a consulta é sempre executada no método acessor e não mais no método de pesquisa. Enfim, isso foi um exemplo, o que você precisa entender é que a cada request você precisa dar um jeito de teu método produtos() retornar a mesma lista :slight_smile:

Abraços e boa sorte.

Olá Rafael!

Primeiramente gostaria de parabenizá-lo pelo seu grupo no google no qual participo.

Na realidade meu problema nao é com a lista.
Eu segui seu exemplo (JSF+AJAX de maneira eficiente) do teu blog mas eu não queria usar o Tomahawk.
O problema que tenho é quando eu seleciono um registro no <a4j:datatable .../>, o mesmo é transferido para um objeto (q representa a linha selecionada). Este objeto é apresentado normalmente no form de manutenção. Quando eu clico em um <a4j:commandButton action="#{meuMB.gravar}" ... /> ele chama o método gravar no MB, só que o objeto é "perdido", fica null, creio q seja porquê o MB foi instanciado novamente.
Como posso resolver isso?

Desde já agradeço sua atenção

Opa, obrigado :slight_smile: O grupo existe realmente para troca de conhecimentos e experiência!

Bem, em escopo de request o seu managed bean será instanciado novamente e consequentemente o teu objeto que representa o formulário também o será, em seguida os dados do formulário serão convertidos e setados neste teu objeto.

O que está estranho é que seu objeto não deveria chegar como null no managed bean já que o formulário irá setar os valores dele na fase de atualização do modelo!

Poderia mostrar algum trecho de código deste formulário e o método de ação?
Abraços.

plantaCRUD.xhtml

[code]<?xml version=“1.0” encoding=“ISO-8859-1”?>
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>

<ui:composition xmlns=“http://www.w3.org/1999/xhtml
xmlns:ui=“http://java.sun.com/jsf/facelets
xmlns:h=“http://java.sun.com/jsf/html
xmlns:f=“http://java.sun.com/jsf/core
xmlns:a4j=“http://richfaces.org/a4j
xmlns:rich=“http://richfaces.org/rich
xmlns:c=“http://java.sun.com/jstl/core
template="/pages/myCrudTemplate.xhtml">

&lt;!-- passa par&#65533;metro para o template --&gt;
&lt;ui:param name="defaultBean" value="#{plantaMB}" /&gt;

&lt;ui:define name="title"&gt;
    Cadastro de Plantas	        
&lt;/ui:define&gt;

&lt;ui:define name="head"&gt;
    &lt;style  type="text/css"&gt;
        .odd-row {
            background-color: #ECF3FE;
        }
        .even-row {
            background-color: #FCFFFE;
        }
    &lt;/style&gt;
&lt;/ui:define&gt;

&lt;!-- define searchlistBlock --&gt;
&lt;ui:define name="searchlistBlock"&gt;
    &lt;rich:dataTable border="2" value="#{plantaMB.listaPlantas}" var="planta" width="320"&gt;                        
        &lt;rich:column sortBy="#{planta.id}"&gt;
            &lt;f:facet name="header"&gt;
                &lt;h:outputText value="Código" /&gt;
            &lt;/f:facet&gt;
            
            &lt;h:commandLink value="#{planta.id}" action="#{plantaMB.editar}" &gt;
                &lt;f:setPropertyActionListener target="#{plantaMB.planta}" value="#{planta}"/&gt;
            &lt;/h:commandLink&gt;
            
        &lt;/rich:column&gt;
        &lt;rich:column sortBy="#{planta.nomePopular}" filterBy="#{planta.nomePopular}" filterEvent="onkeyup"&gt;
            &lt;f:facet name="header"&gt;
                &lt;h:outputText value="Nome Popular" /&gt;
            &lt;/f:facet&gt;
            &lt;h:outputText value="#{planta.nomePopular}"/&gt;
        &lt;/rich:column&gt;
        &lt;rich:column sortBy="#{planta.nomeCientifico}"&gt;
            &lt;f:facet name="header"&gt;
                &lt;h:outputText value="Nome Cientifico" /&gt;
            &lt;/f:facet&gt;
            &lt;h:outputText value="#{planta.nomeCientifico}"/&gt;
        &lt;/rich:column&gt;
        &lt;rich:column sortBy="#{planta.dataAquisicao}"&gt;
            &lt;f:facet name="header"&gt;
                &lt;h:outputText value="Data aquisição" /&gt;
            &lt;/f:facet&gt;
            &lt;h:outputText value="#{planta.dataAquisicao}"/&gt;
        &lt;/rich:column&gt;
        &lt;rich:column sortBy="#{planta.idadeNaAquisicao}"&gt;
            &lt;f:facet name="header"&gt;
                &lt;h:outputText value="Idade aquisição" /&gt;
            &lt;/f:facet&gt;
            &lt;h:outputText value="#{planta.idadeNaAquisicao}"/&gt;
        &lt;/rich:column&gt;                                   
    &lt;/rich:dataTable&gt;                                    		
    
&lt;/ui:define&gt;

&lt;!-- define addUpdateBlock --&gt;
&lt;ui:define name="addUpdateBlock"&gt;
    &lt;h:inputHidden id="idplanta" value="#{plantaMB.planta.id}"/&gt;
    &lt;h:panelGrid id="painel_grid" columns="2" &gt;                                                         
        &lt;h:outputLabel value="Nome Científico" for="nomeCientifico"/&gt;
        &lt;h:panelGroup&gt;
            &lt;h:inputText id="nomeCientifico" value="#{plantaMB.planta.nomeCientifico}" maxlength="50" required="true"&gt;                                                                            
            &lt;/h:inputText&gt;
            &lt;rich:message id="mensagem_nomeCientifico" for="nomeCientifico"&gt;                                                                
                &lt;f:facet name="errorMarker"&gt;
                    &lt;h:graphicImage value="/images/error.gif" /&gt;   
                &lt;/f:facet&gt;
            &lt;/rich:message&gt;                            
        &lt;/h:panelGroup&gt;
        
        &lt;h:outputLabel value="Nome Popular" for="nomePopular"/&gt;
        &lt;h:panelGroup&gt;
            &lt;h:inputText id="nomePopular" value="#{plantaMB.planta.nomePopular}" maxlength="50" required="true"&gt;                                                                            
            &lt;/h:inputText&gt;
            &lt;rich:message id="mensagem_nomePopular" for="nomePopular"&gt;                                                                
                &lt;f:facet name="errorMarker"&gt;
                    &lt;h:graphicImage value="/images/error.gif" /&gt;   
                &lt;/f:facet&gt;
            &lt;/rich:message&gt;                            
        &lt;/h:panelGroup&gt;                                                                
        
    &lt;/h:panelGrid&gt;        
    &lt;h:messages showDetail="true" /&gt;
    &lt;h:commandButton value="Gravar" action="#{plantaMB.salvar}" /&gt;                                                        
&lt;/ui:define&gt;

</ui:composition>[/code]

plantaMB.java

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.keko.mb;

import br.keko.dao.PlantaDAO;
import br.keko.modelo.Planta;
import br.keko.utils.JPAHelper;
import javax.faces.model.ListDataModel;
import javax.persistence.EntityManager;

/**
 *
 * @author Abner
 */
public class plantaMB {

    public static final String PESQUISAR_STATE = "pesquisar";
    public static final String ADICIONAR_STATE = "adicionar";
    public static final String EDITAR_STATE = "editar";
    private String currentState = PESQUISAR_STATE;
    private Planta planta;
    private PlantaDAO dao = new PlantaDAO();
    private ListDataModel listaPlantas;

    public plantaMB() {
        planta = new Planta();
        consultar();
    }

    public Planta getPlanta() {
        return planta;
    }

    public void setPlanta(Planta planta) {
        this.planta = planta;
    }

    public PlantaDAO getDao() {
        return dao;
    }

    public void setDao(PlantaDAO dao) {
        this.dao = dao;
    }

    public ListDataModel getListaPlantas() {
        return listaPlantas;
    }

    public void setListaPlantas(ListDataModel listaPlantas) {
        this.listaPlantas = listaPlantas;
    }

    
    public void editar() {
        //setPlanta((Planta)getListaPlantas().getRowData());
        setCurrentState(EDITAR_STATE);
    }

    public void salvar() {
        EntityManager em = JPAHelper.createEntityManager();
        getDao().setEntityManager(em);
        
        em.getTransaction().begin();
        getDao().salvar(getPlanta());
        em.getTransaction().commit();
        em.close();
        this.setCurrentState(PESQUISAR_STATE);
    }

    public void consultar() {
        EntityManager em = JPAHelper.createEntityManager();
        getDao().setEntityManager(em);
        setListaPlantas(getDao().getAll(Planta.class));
        em.close();
        this.setCurrentState(PESQUISAR_STATE);
    }

    public boolean isPesquisarState() {
        String state = this.getCurrentState();
        return (state == null || PESQUISAR_STATE.equals(state));
    }

    public boolean isAdicionarState() {
        return ADICIONAR_STATE.equals(this.getCurrentState());
    }

    public boolean isEditarState() {
        return EDITAR_STATE.equals(this.getCurrentState());
    }

    public String getCurrentState() {
        return currentState;
    }

    public void setCurrentState(String currentState) {
        this.currentState = currentState;
    }
}

Se quiser eu mando o projeto.

Obrigado desde já

rafael, esquece.
Eu descobri o problema, no meu path eu tava com 2 lib de implementacoes diferentes de jsf…
Valeu pela ajuda!

Obs.: Põe mais artigo lah no teu blog… eu curto ler seus artigos