Problema com Rowkey do Primefaces 3.0 M3

Ola, estou usando o Primeafaces 3.0 M3 e inseri uma dataTable com o atributo RowKey porque sem ele a datatable não atualiza quando insiro um objeto na lista dela.
Mas, no meu sistema não é obrigatorio que todas as datatables (3 ao total) da página tenham dados inseridos.
O problema vem agora: como não é obrigatório alguma pode ficar sem objetos, porém, na hora de inserir ele reclama se alguma das datatables não tiver conteudo preenchido com o seguinte erro:

INFO: javax.faces.FacesException: Cannot find data with given rowKey:beans.CicloContato[id=null]
javax.faces.FacesException: Cannot find data with given rowKey:beans.CicloContato[id=null]
	at org.primefaces.component.datatable.DataTable.getRowData(DataTable.java:878)
	at org.primefaces.component.datatable.DataHelper.decodeSingleSelection(DataHelper.java:232)
	at org.primefaces.component.datatable.DataHelper.decodeSelection(DataHelper.java:223)
	at org.primefaces.component.datatable.DataTableRenderer.decode(DataTableRenderer.java:61)
	at javax.faces.component.UIComponentBase.decode(UIComponentBase.java:787)
	at javax.faces.component.UIData.processDecodes(UIData.java:1162)
	at org.primefaces.component.datatable.DataTable.processDecodes(DataTable.java:575)
	at javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:1176)
	at javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:1176)
	at org.primefaces.component.panel.Panel.processDecodes(Panel.java:282)
	at javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:1176)
	at org.primefaces.component.tabview.TabView.processDecodes(TabView.java:267)
	at javax.faces.component.UIForm.processDecodes(UIForm.java:225)
	at com.sun.faces.context.PartialViewContextImpl$PhaseAwareVisitCallback.visit(PartialViewContextImpl.java:506)
	at com.sun.faces.component.visit.PartialVisitContext.invokeVisitCallback(PartialVisitContext.java:183)
	at javax.faces.component.UIComponent.visitTree(UIComponent.java:1589)
	at javax.faces.component.UIForm.visitTree(UIForm.java:335)
	at javax.faces.component.UIComponent.visitTree(UIComponent.java:1600)
	at javax.faces.component.UIComponent.visitTree(UIComponent.java:1600)
	at javax.faces.component.UIComponent.visitTree(UIComponent.java:1600)
	at com.sun.faces.context.PartialViewContextImpl.processComponents(PartialViewContextImpl.java:376)
	at com.sun.faces.context.PartialViewContextImpl.processPartial(PartialViewContextImpl.java:252)
	at javax.faces.context.PartialViewContextWrapper.processPartial(PartialViewContextWrapper.java:183)
	at javax.faces.context.PartialViewContextWrapper.processPartial(PartialViewContextWrapper.java:183)
	at javax.faces.component.UIViewRoot.processDecodes(UIViewRoot.java:931)
	at com.sun.faces.lifecycle.ApplyRequestValuesPhase.execute(ApplyRequestValuesPhase.java:78)
	at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
	at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
	at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593)
	at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1539)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:281)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
	at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655)
	at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)
	at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:98)
	at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:91)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:162)
	at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:330)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231)
	at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:174)
	at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:828)
	at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:725)
	at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1019)
	at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:225)
	at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
	at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
	at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
	at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
	at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
	at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
	at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
	at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
	at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
	at java.lang.Thread.run(Thread.java:662)

Alguém sabe o porque disso estar ocorrendo?

descobriu? … estou como mesmo problema

Parece ser um pequeno bug da versão 3…03M. Esse rowkey é novo. Baixei a 3 RC1 Snapshot e continua com esse problema. Deve ser corrigido nas próximas atualizações.

consegui aqui … tinha tem dois jeitos … ou você declara rowkey na tag do p:dataTable ou faz o retorno do value receber uma instância de PrimeDataModel (que não existe na API por sinal)

[code]/*

  • Copyright 2009-2011 Prime Technology.
  • Licensed under the Apache License, Version 2.0 (the “License”);
  • you may not use this file except in compliance with the License.
  • You may obtain a copy of the License at
  • http://www.apache.org/licenses/LICENSE-2.0
  • Unless required by applicable law or agreed to in writing, software
  • distributed under the License is distributed on an “AS IS” BASIS,
  • WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  • See the License for the specific language governing permissions and
  • limitations under the License.
    */
    package org.primefaces.model;

import java.io.Serializable;
import javax.faces.model.ListDataModel;

/**

  • An implementation of SelectableDataModel using a list as data
    */
    public class PrimeDataModel extends ListDataModel implements SelectableDataModel, Serializable {

    public PrimeDataModel() {}

    public PrimeDataModel(Object data) {
    setWrappedData(data);
    }

    public Object getRowKey(T object) {
    throw new UnsupportedOperationException(“Must be implemented”);
    }

    public T getRowData(String rowKey) {
    throw new UnsupportedOperationException(“Must be implemented”);
    }
    }[/code]

a minha implementação do PrimeDataModel

[code]
import java.util.List;

import org.primefaces.model.PrimeDataModel;

import com.engecorps.gaia.entity.SysUser;

@SuppressWarnings(“serial”)
public class UserDataModel extends PrimeDataModel {

public UserDataModel() {
}

public UserDataModel(Object data) {
    super(data);
}

@Override
public SysUser getRowData(String rowKey) {
    //In a real app, a more efficient way like a query by rowKey should be implemented to deal with huge data
    
    List<SysUser> users = (List<SysUser>) getWrappedData();
    
    for(SysUser user : users) {
    	String id = ""+user.getId();
        if(id.equals(rowKey))
            return user;
    }
    
    return null;
}

@Override
public String getRowKey(SysUser user) {
    return ""+user.getId();
}

}[/code]

o meu bean

[code]
import java.io.Serializable;
import java.util.List;

import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;

import org.primefaces.event.SelectEvent;
import org.primefaces.event.UnselectEvent;

import com.engecorps.gaia.engine.ControllerEngine;
import com.engecorps.gaia.entity.SysUser;

@SuppressWarnings(“serial”)
@ManagedBean(name = “userController”)
@RequestScoped
public class UserController implements Serializable {

private List<SysUser> users;

private UserDataModel usersModel;

private SysUser selectedUser;

public UserController() {
	users = ControllerEngine.load(SysUser.class);
	usersModel = new UserDataModel(users);
	
	selectedUser = new SysUser();
}

public void onRowSelect(SelectEvent event) {
    FacesMessage msg = new FacesMessage("User Selected", ""+((SysUser) event.getObject()).getId());

    FacesContext.getCurrentInstance().addMessage(null, msg);
this.setSelectedUser((SysUser) event.getObject());
}

public void onRowUnselect(UnselectEvent event) {
    FacesMessage msg = new FacesMessage("User Unselected", ""+((SysUser) event.getObject()).getId());

    FacesContext.getCurrentInstance().addMessage(null, msg);
}

public String onRowSelectNavigate(SelectEvent event) {
    FacesContext.getCurrentInstance().getExternalContext().getFlash().put("selectedUser", event.getObject());

    return "userDetail?faces-redirect=true";
}

public void persist(ActionEvent actionEvent) { 
    FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Info", "Changes Saved"));
    ControllerEngine.persist(selectedUser);
}

public void persist() { 
    FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Info", "Changes Saved"));
    ControllerEngine.persist(selectedUser);
}

public void newPersist() { 
    System.out.println("foi?");
    ControllerEngine.persist(selectedUser);
selectedUser = new SysUser();
}


public List<SysUser> getUsers() {
	return users;
}

public UserDataModel getUsersModel() {
	return usersModel;
}

public SysUser getSelectedUser() {
	return selectedUser;
}

public void setSelectedUser(SysUser selectedUser) {
	this.selectedUser = selectedUser;
}

}[/code]

e pro fim o xhtml

[code]<?xml version='1.0' encoding='UTF-8' ?>

<f:view contentType=“text/html”>
<h:head>
EGC Intranet



<ui:insert name=“head”></ui:insert>

</h:head>

<h:body>
	<h:form id="form">
		<p:growl id="growl" showDetail="true" />
	
		<p:dataTable id="users" var="user" value="#{userController.usersModel}" emptyMessage="Nenhum usuário encontrado."
					paginator="true" rows="10" rowsPerPageTemplate="5,10,15" 
					selection="#{userController.selectedUser}" selectionMode="single" >

			<p:ajax event="rowSelect" listener="#{userController.onRowSelect}" update=":form:display :form:growl" oncomplete="userDialog.show()" />
			<p:ajax event="rowUnselect" listener="#{userController.onRowUnselect}" update=":form:growl" />
			
			<f:facet name="header">
				<h:outputText value="Usuários" />
			</f:facet>

			<p:column >
				<f:facet name="header">
					<h:outputText value="Id" />
				</f:facet>
				<h:outputText value="#{user.id}" />
			</p:column>
			
			<p:column >
				<f:facet name="header">
					<h:outputText value="Login" />
				</f:facet>
				<h:outputText value="#{user.nickName}" />
			</p:column>

			<p:column >
				<f:facet name="header">
					<h:outputText value="Nome Completo" />
				</f:facet>
				<h:outputText value="#{user.fullName}" />
			</p:column>

			<p:column >
				<f:facet name="header">
					<h:outputText value="Email" />
				</f:facet>
				<h:outputText value="#{user.emailCompany}" />
			</p:column>

			<p:column >
				<f:facet name="header">
					<h:outputText value="Grupo" />
				</f:facet>
				<h:outputText value="#{user.group.name}" />
			</p:column>

			<p:column >
				<f:facet name="header">
					<h:outputText value="Data de Nascimento" />
				</f:facet>
				<h:outputText value="#{user.birthDay}" />
			</p:column>
		</p:dataTable>

		<p:dialog id="userDlg" header="Usuário" widgetVar="userDialog" resizable="false" showEffect="explode" hideEffect="explode">

			<h:panelGrid id="display" columns="2" cellpadding="4">

				<h:outputText value="Login:" />
				<h:inputText value="#{userController.selectedUser.nickName}" />

				<h:outputText value="Password:" />
				<h:inputText value="#{userController.selectedUser.password}" />

				<h:outputText value="Nome Completo:" />
				<h:inputText value="#{userController.selectedUser.fullName}" />


				<h:outputText value="Email:" />
				<p:inputMask value="#{userController.selectedUser.emailCompany}" mask="(999) 999-9999" />

				<h:outputText value="Email Pessoal:" />
				<p:inputMask value="#{userController.selectedUser.emailHome}" mask="(999) 999-9999" />
							

                 <f:facet name="footer">
                     <p:outputPanel layout="block" style="text-align:right">
                         <p:commandButton value="Save" update=":form:users :form:growl" actionListener="#{userController.persist}" oncomplete="onEditComplete(xhr,status,args)"
                                          image="ui-icon ui-icon-check"/>
                         <p:commandButton value="Cancel" onclick="userDialog.hide()" type="button" image="ui-icon ui-icon-close"/>
                         
                     </p:outputPanel>
                 </f:facet>
			</h:panelGrid>
		</p:dialog>
	</h:form>
</h:body>

</f:view>

[/code]

Eu estou inserindo o rowKey na tag <p:dataTable> e está dando esse erro tmb:

WARNING: Cannot find data with given rowKey:null
javax.faces.FacesException: Cannot find data with given rowKey:null
	at org.primefaces.component.datatable.DataTable.getRowData(DataTable.java:878)
	at org.primefaces.component.datatable.DataHelper.decodeSingleSelection(DataHelper.java:232)
	at org.primefaces.component.datatable.DataHelper.decodeSelection(DataHelper.java:223)
	at org.primefaces.component.datatable.DataTableRenderer.decode(DataTableRenderer.java:61)
	at javax.faces.component.UIComponentBase.decode(UIComponentBase.java:790)
	at javax.faces.component.UIData.processDecodes(UIData.java:980)
	at org.primefaces.component.datatable.DataTable.processDecodes(DataTable.java:575)
	at javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:1042)
	at org.primefaces.component.dialog.Dialog.processDecodes(Dialog.java:360)
	at javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:1042)
	at javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:1042)
	at javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:1042)
	at javax.faces.component.UIForm.processDecodes(UIForm.java:216)
	at javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:1042)
	at javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:1042)
	at javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:1042)
	at javax.faces.component.UIViewRoot.processDecodes(UIViewRoot.java:941)
	at com.sun.faces.lifecycle.ApplyRequestValuesPhase.execute(ApplyRequestValuesPhase.java:78)
	at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
	at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
	at javax.faces.webapp.FacesServlet.service(FacesServlet.java:312)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
	at br.com.aequalis.filter.FilterLogin.doFilter(FilterLogin.java:36)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
	at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:845)
	at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
	at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
	at java.lang.Thread.run(Thread.java:619)
&lt;p:dataTable value="#{membroProjetoController.cidades}" var="cidade"
				styleClass="table"
				rowSelectListener="#{membroProjetoController.selectCidade}"
				selectionMode="single" rowKey="#{cidade.idCidade}"
				selection="#{membroProjetoController.endereco.cidade}"
				onRowSelectUpdate="nomecidade"
				onRowSelectComplete="cidadeselect.hide()"&gt;
				&lt;f:facet name="header"&gt;Cidades&lt;/f:facet&gt;
				&lt;p:column headerText="Código" &gt;
					#{cidade.idCidade}
				&lt;/p:column&gt;
				&lt;p:column headerText="Nome"&gt;
					#{cidade.nome}
				&lt;/p:column&gt;
				&lt;p:column headerText="Estado"&gt;
					#{cidade.estado.nome}
				&lt;/p:column&gt;
			&lt;/p:dataTable&gt;

alguém conseguiu resolver esse problema?

Fernando

esse teu value="#{membroProjetoController.cidades}" … retona um List ?

faz ele retornar uma instância de PrimeDataModel … olha como eu fiz ali em cima … no meu vai certo …

é simples implementar ela … só um passo a mais … depois pode tirar o rowkey, pois ele ja fica definido nessa tua implementação de PrimeDataModel

O método retorna um List<Cidade>…
Onde tu inseriu essa classe PrimeDataModel?? Qual pacote??

Boa noite!

Daniel, esse seu PrimeDataModel também é Lazy? Ou somente mostra os dados no p:dataTable de uma lista?

Não consegui fazer funcionar com o LazyDataModel… da erro nestes métodos getRowKey e getRowData.

Até +!

O LazyDataModel já implementaria essas funções, mas não está funcionando. Também tentei usa-lo e não consegui

Engraçado que nos forums do primefaces eles dizem que vc deve sobrescrever esses métodos.

Paliativamente, consegui resolver assim (usando hibernate):

    @Override
    public Pessoa getRowData(String rowKey)
    {
        dao = new DAOGenerico(Pessoa.class);
        Pessoa objeto = (Pessoa) dao.buscarPorID(Long.parseLong(rowKey),ss); //método do DAO que busca um registro pelo id.
        return objeto;
    }

    @Override
    public String getRowKey(Pessoa objeto)
    {
        return objeto.getId().toString();
    }

Por enquanto está funcionando…

Até +!

sobreescrever os da LazyDataModel ?

Sim.

Valeu, esse post foi muito util !!!

Muito bom o post me ajudo muito vlww :wink: