DataModel em escopo de request

Olá pessoal,

Estou tentando utilizar o escopo de request, porém, ocorre o seguinte erro:

java.io.NotSerializableException: javax.faces.model.ListDataModel

Esse é o método que faz a pesquisa no banco de dados:

    	    EntityManagerFactory emf = EntityManagerProvider.getEntityManagerFactory();
    	    EntityManager em = emf.createEntityManager();
    		Query q = em.createQuery(sqlPesquisa + sqlOrdemPesquisa);
    	    List<Modelo> r = (ArrayList<Modelo>) q.getResultList();
    	    dmRegistros = new ListDataModel(r);    	    
    	    em.close();

Olá amigo.
Isso se dá ao fato de sua classe “Modelo” ou essa classe que acessa o banco de dados, não é uma classe serializável.

Basta adicionar algo como:


public class Cliente implements Serializable {
...
}

Obrigado lessandronp!

Agora não aprece mais o erro, porém, não estou conseguindo usar o keepAlive. Quando faço a pesquisa o dataModel é populado, mas quando clico no botao para alterar os dados somem.

O MB está em escopo de request no faces-config e estou usando <a4j:keepAlive beanName=“departamentoMB” /> no XHML.

segue meu codigo:
MB

public class DepartamentoMB implements Serializable{
	Modelo modelo = new Departamento();

	public void ler(){ 
    	try {
    	    EntityManagerFactory emf = EntityManagerProvider.getEntityManagerFactory();
    	    EntityManager em = emf.createEntityManager();
    		Query q = em.createQuery(sqlPesquisa + sqlOrdemPesquisa);
    		q.setMaxResults(maxRowsLer);
    		q.setHint("org.hibernate.cacheable", true);  
    		q.setHint("org.hibernate.cacheMode", CacheMode.NORMAL);
    	    List<Modelo> r = (ArrayList<Modelo>) q.getResultList();
    	    dmRegistros = new ListDataModel(r);
       }

JSF

<ui:composition template="/templates/principal.xhtml">
	<a4j:keepAlive beanName="departamentoMB" />
	<head>
		<meta http-equiv="content-Type" content="text/html; charset=utf-8"></meta>		
	</head>
	<body>
		<ui:define name="centro">
			<f:subview id="subviewDepartamento">
				<rich:toolBar>
					<a4j:commandButton action="#{departamentoMB.ler}" value="Localizar" reRender="departamentoLista"/>							
								</rich:toolBar>					
				<a4j:outputPanel ajaxRendered="true">										
				<rich:dataTable value="#{departamentoMB.dmRegistros}" id="departamentoLista" rows="9" var="departamentos">
					 <a4j:support event="onkeyup" />
						<f:facet name="header">
							<rich:columnGroup>
								<rich:column>
								<h:outputText styleClass="headerText" value="Id" />
							</rich:column>
							<rich:column>
								<h:outputText value="Departamento" />
							</rich:column>
							<rich:column>
								<h:outputText value="Ação" />
							</rich:column>
							</rich:columnGroup>
						</f:facet>
						<rich:column width="70">
							<h:outputText value="#{departamentos.id}" />
						</rich:column>
						<rich:column width="660">
							<h:outputText value="#{departamentos.departamento}" />
						</rich:column>
						<rich:column width="50" align="center">
							<a4j:commandButton action="#{departamentoMB.atualizar}" title="Alterar" image="/imagens/ImagensUtilizadas/16x16/viewmag.png"/>
							<a4j:commandButton reRender="table" image="/imagens/ImagensUtilizadas/16x16/remove.png"
                				   action="#{departamentoMB.marcaRemover}" title="Excluir" oncomplete="javascript:Richfaces.showModalPanel('panelModal');"/>                						      							      	
										</rich:column>
									</rich:dataTable>	
									<rich:datascroller align="left" for="departamentoLista" maxPages="20" id="ds1" />
									</a4j:outputPanel>									

Provavelmente sumirão mesmo… O ideal seria utilizar o MB como session e o Bean como request.
Mas se quiser manter dessa forma tente fazer algo como:
Cria no MB um atributo do tipo:

private Departamento departamentoSelecionado;

getters and setters pra esse cara.

Nesse caso vc está setando o departamento selecionado na grid para o seu MB. Com isso no método alterar, vc passa o departamentoSelecionado.

&lt;a4j:commandButton value="#{msg['botao.alterar']}" styleClass="botoes" action="#{departamentoMB.atualizar}"&gt;
       &lt;f:setPropertyActionListener value="#{departamentoMB.departamentoSelecionado}" target="#{departamentos}" /&gt;
&lt;/a4j:commandButton&gt;

Veja se isso te ajuda… Porque dessa forma vc consegue passar para o MB o cara q vc selecionou na grid e após alterar ele, o MB consegue
capturá-lo passando pro DataModel.

Abraços,
Lessandro

Obrigado lessandronp!

Mas é correto colocar o MB na sessão? Sempre ouvi dizer para colocar no resquest!

Hoje meu Bean esta dentro do MB, se eu colocar o MB na sessão, tudo ficara na sessao nao é?

Olha, cada um usa de uma forma diferente. Cada pessoa adota um padrão de desenvolvimento. Agora com o JSF 2.0 as coisas ficaram
mais “encorpadas”, pois os escopos de sessao, requisição, entre outros escopos possuem seu tempo de vida maior ou menor dependendo
do utilizado. Agora não necessariamente seu Bean terá escopo de sessão, afinal se vc der um “New” no seu Bean ele sempre será criado.
Quando instanciado o seu Bean se este foi declarado como Request, ao instanciá-lo também, independente do seu MB ser Session, seu Bean
será Request. A não ser que utilize “ManagedBean.Bean.nome” por exemplo.
Talvez o mais correto fosse na sua página JSF vc utilizar Bean.nome. Os actions dos seus botões, e acesso a alguma lista que não existe no seu
Bean, aí sim, vc acessará do MB.
Abs,
Lessandro