jsf primefaces jsf-2.2

jsf - java.lang.UnsupportedOperationException: getRowData(String rowKey) debe implementarse cuando no se utiliza el algoritmo RowKey básico



primefaces jsf-2.2 (1)

Como se menciona en este enlace que apunta al Foro de la comunidad PrimeFaces,

Cambiamos esa parte por diseño porque el manejo de atributo rowKey con un LazyDataModel no es correcto.

Esos dos métodos getRowKey() y getRowData() deben implementarse en el bean administrado asociado siempre que se LazyDataModel<T> como se muestra en la pregunta.

De PrimeFaces User Guide (PDF) - (5.1 (página 164) y 5.2 (página 166)):

Lazy Lazy es un enfoque para tratar con enormes conjuntos de datos de manera eficiente, la paginación regular basada en ajax funciona al representar solo una página en particular, pero aún requiere que todos los datos se carguen en la memoria. La datatable de carga diferida representa una página en particular de manera similar, pero también solo carga los datos de la página en la memoria, no todo el conjunto de datos. Para implementar esto, necesitarás vincular un org.primefaces.model.LazyDataModel como el valor e implementar el método de carga y habilitar la opción perezosa. También se requiere implementar getRowData y getRowKey si tiene habilitada la selección.

El atributo rowKey se puede usar, cuando lazy está desactivada, se establece en false (valor predeterminado) y la selección de fila se habilita.

De PrimeFaces User Guide (PDF) - (5.1 (página 159) y 5.2 (página 161)):

RowKey debe ser un identificador único de su modelo de datos y utilizado por datatable para encontrar las filas seleccionadas. Puede definir esta clave utilizando el atributo rowKey o vinculando un modelo de datos que implementa org.primefaces.model.SelectableDataModel .

Como,

<p:dataTable var="car" value="#{carBean.cars}" selection="#{carBean.selectedCars}" rowKey="#{car.id}"> <p:column selectionMode="multiple"/> <!--columns--> </p:dataTable>

Actualicé PrimeFaces de 5.1 final a 5.2 final (Community Release). Tengo un <p:dataTable> que se carga de forma perezosa de la siguiente manera (un ejemplo mínimo para reproducir el problema con fines puramente de prueba).

<p:dataTable var="row" value="#{testManagedBean}" lazy="true" editable="true" rowKey="#{row.fruitId}" selection="#{testManagedBean.selectedValues}" rows="50"> <p:column selectionMode="multiple"/> <p:ajax event="rowEdit" listener="#{testManagedBean.onRowEdit}"/> <p:column headerText="Id"> <h:outputText value="#{row.fruitId}"/> </p:column> <p:column headerText="Fruit Name"> <p:cellEditor> <f:facet name="output"> <h:outputText value="#{row.fruitName}"/> </f:facet> <f:facet name="input"> <p:inputText value="#{row.fruitName}"/> </f:facet> </p:cellEditor> </p:column> <p:column headerText="Price"> <p:cellEditor> <f:facet name="output"> <h:outputText value="#{row.price}"/> </f:facet> <f:facet name="input"> <p:inputText value="#{row.price}"/> </f:facet> </p:cellEditor> </p:column> <p:column headerText="Edit"> <p:rowEditor/> </p:column> </p:dataTable>

El bean gestionado correspondiente:

@Named @ViewScoped public class TestManagedBean extends LazyDataModel<Fruit> implements Serializable { private List<Fruit> selectedValues; // Getter & setter. private static final long serialVersionUID = 1L; public TestManagedBean() {} private List<Fruit> init() { List<Fruit> fruits = new ArrayList<Fruit>(); Fruit fruit = new Fruit(); fruit.setFruitId(1); fruit.setFruitName("Mango"); fruit.setPrice(500D); fruits.add(fruit); fruit = new Fruit(); fruit.setFruitId(2); fruit.setFruitName("Guava"); fruit.setPrice(300D); fruits.add(fruit); fruit = new Fruit(); fruit.setFruitId(3); fruit.setFruitName("Apple"); fruit.setPrice(600D); fruits.add(fruit); return fruits; } @Override public List<Fruit> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, Object> filters) { List<Fruit> fruits = init(); setRowCount(fruits.size()); return fruits; } public void onRowEdit(RowEditEvent event) { System.out.println("id : "+((Fruit)event.getObject()).getFruitId()); } }

Al editar el método onRowEdit() se supone que debe invocarse a lo que está vinculado,

<p:ajax event="rowEdit" listener="#{testManagedBean.onRowEdit}"/>

Cuando una fila se encuentra en un modo de edición y se hace clic en el enlace de actualización marcado con una marca, se produce la siguiente excepción.

Info: java.lang.UnsupportedOperationException: getRowData(String rowKey) must be implemented when basic rowKey algorithm is not used. java.lang.UnsupportedOperationException: getRowData(String rowKey) must be implemented when basic rowKey algorithm is not used. at org.primefaces.model.LazyDataModel.getRowData(LazyDataModel.java:95) at org.primefaces.component.datatable.DataTable.getRowData(DataTable.java:1214) at org.primefaces.component.datatable.feature.SelectionFeature.decodeMultipleSelection(SelectionFeature.java:90) at org.primefaces.component.datatable.feature.SelectionFeature.decode(SelectionFeature.java:48) at org.primefaces.component.datatable.DataTableRenderer.decode(DataTableRenderer.java:62) at javax.faces.component.UIComponentBase.decode(UIComponentBase.java:834) at org.primefaces.component.api.UIData.processDecodes(UIData.java:281) at com.sun.faces.context.PartialViewContextImpl$PhaseAwareVisitCallback.visit(PartialViewContextImpl.java:573) at com.sun.faces.component.visit.PartialVisitContext.invokeVisitCallback(PartialVisitContext.java:183) at org.primefaces.component.api.UIData.visitTree(UIData.java:821) at javax.faces.component.UIComponent.visitTree(UIComponent.java:1690) at javax.faces.component.UIForm.visitTree(UIForm.java:380) at javax.faces.component.UIComponent.visitTree(UIComponent.java:1690) at javax.faces.component.UIComponent.visitTree(UIComponent.java:1690) at com.sun.faces.context.PartialViewContextImpl.processComponents(PartialViewContextImpl.java:403) at com.sun.faces.context.PartialViewContextImpl.processPartial(PartialViewContextImpl.java:266) at org.primefaces.context.PrimePartialViewContext.processPartial(PrimePartialViewContext.java:60) at javax.faces.component.UIViewRoot.processDecodes(UIViewRoot.java:930) 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:198) at javax.faces.webapp.FacesServlet.service(FacesServlet.java:660) at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1682) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:318) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160) at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:734) at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:673) at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:174) at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:415) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:282) at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:459) at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:167) at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:201) at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:175) at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:235) at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119) at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:284) at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:201) at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:133) at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:112) at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77) at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:561) at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112) at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117) at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56) at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137) at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:565) at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:545) at java.lang.Thread.run(Thread.java:745) Warning: java.lang.UnsupportedOperationException: getRowData(String rowKey) must be implemented when basic rowKey algorithm is not used. javax.faces.FacesException: java.lang.UnsupportedOperationException: getRowData(String rowKey) must be implemented when basic rowKey algorithm is not used. at com.sun.faces.context.PartialViewContextImpl.processPartial(PartialViewContextImpl.java:273) at org.primefaces.context.PrimePartialViewContext.processPartial(PrimePartialViewContext.java:60) at javax.faces.component.UIViewRoot.processDecodes(UIViewRoot.java:930) 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:198) at javax.faces.webapp.FacesServlet.service(FacesServlet.java:660) at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1682) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:318) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160) at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:734) at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:673) at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:174) at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:415) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:282) at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:459) at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:167) at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:201) at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:175) at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:235) at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119) at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:284) at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:201) at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:133) at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:112) at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77) at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:561) at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112) at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117) at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56) at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137) at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:565) at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:545) at java.lang.Thread.run(Thread.java:745) Caused by: java.lang.UnsupportedOperationException: getRowData(String rowKey) must be implemented when basic rowKey algorithm is not used. at org.primefaces.model.LazyDataModel.getRowData(LazyDataModel.java:95) at org.primefaces.component.datatable.DataTable.getRowData(DataTable.java:1214) at org.primefaces.component.datatable.feature.SelectionFeature.decodeMultipleSelection(SelectionFeature.java:90) at org.primefaces.component.datatable.feature.SelectionFeature.decode(SelectionFeature.java:48) at org.primefaces.component.datatable.DataTableRenderer.decode(DataTableRenderer.java:62) at javax.faces.component.UIComponentBase.decode(UIComponentBase.java:834) at org.primefaces.component.api.UIData.processDecodes(UIData.java:281) at com.sun.faces.context.PartialViewContextImpl$PhaseAwareVisitCallback.visit(PartialViewContextImpl.java:573) at com.sun.faces.component.visit.PartialVisitContext.invokeVisitCallback(PartialVisitContext.java:183) at org.primefaces.component.api.UIData.visitTree(UIData.java:821) at javax.faces.component.UIComponent.visitTree(UIComponent.java:1690) at javax.faces.component.UIForm.visitTree(UIForm.java:380) at javax.faces.component.UIComponent.visitTree(UIComponent.java:1690) at javax.faces.component.UIComponent.visitTree(UIComponent.java:1690) at com.sun.faces.context.PartialViewContextImpl.processComponents(PartialViewContextImpl.java:403) at com.sun.faces.context.PartialViewContextImpl.processPartial(PartialViewContextImpl.java:266) ... 34 more Severe: java.lang.UnsupportedOperationException: getRowData(String rowKey) must be implemented when basic rowKey algorithm is not used. at org.primefaces.model.LazyDataModel.getRowData(LazyDataModel.java:95) at org.primefaces.component.datatable.DataTable.getRowData(DataTable.java:1214) at org.primefaces.component.datatable.feature.SelectionFeature.decodeMultipleSelection(SelectionFeature.java:90) at org.primefaces.component.datatable.feature.SelectionFeature.decode(SelectionFeature.java:48) at org.primefaces.component.datatable.DataTableRenderer.decode(DataTableRenderer.java:62) at javax.faces.component.UIComponentBase.decode(UIComponentBase.java:834) at org.primefaces.component.api.UIData.processDecodes(UIData.java:281) at com.sun.faces.context.PartialViewContextImpl$PhaseAwareVisitCallback.visit(PartialViewContextImpl.java:573) at com.sun.faces.component.visit.PartialVisitContext.invokeVisitCallback(PartialVisitContext.java:183) at org.primefaces.component.api.UIData.visitTree(UIData.java:821) at javax.faces.component.UIComponent.visitTree(UIComponent.java:1690) at javax.faces.component.UIForm.visitTree(UIForm.java:380) at javax.faces.component.UIComponent.visitTree(UIComponent.java:1690) at javax.faces.component.UIComponent.visitTree(UIComponent.java:1690) at com.sun.faces.context.PartialViewContextImpl.processComponents(PartialViewContextImpl.java:403) at com.sun.faces.context.PartialViewContextImpl.processPartial(PartialViewContextImpl.java:266) at org.primefaces.context.PrimePartialViewContext.processPartial(PrimePartialViewContext.java:60) at javax.faces.component.UIViewRoot.processDecodes(UIViewRoot.java:930) 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:198) at javax.faces.webapp.FacesServlet.service(FacesServlet.java:660) at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1682) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:318) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160) at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:734) at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:673) at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:174) at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:415) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:282) at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:459) at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:167) at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:201) at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:175) at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:235) at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119) at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:284) at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:201) at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:133) at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:112) at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77) at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:561) at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112) at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117) at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56) at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137) at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:565) at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:545) at java.lang.Thread.run(Thread.java:745)

Esto no debería suceder porque rowKey="#{row.fruitId}" se usa con el <p:dataTable> .

La excepción desaparece solo cuando se rowKey atributo rowKey y los getRowKey() y getRowData() se implementan en el bean gestionado asociado de la siguiente manera.

@Override public Object getRowKey(Fruit fruit) { return fruit != null ? fruit.getFruitId() : null; } @Override public Fruit getRowData(String rowKey) { List<Fruit> fruits = (List<Fruit>) getWrappedData(); Integer value = Integer.valueOf(rowKey); for (Fruit fruit : fruits) { if (fruit.getFruitId().equals(value)) { return fruit; } } return null; }

¿Es obligatorio en la versión más reciente de PrimeFaces (5.2 final) que no era necesaria en la versión anterior de PrimeFaces (5.1 final)?

Probado en Mojarra 2.3.0-m02. Supuse que no debería haber ninguna relevancia con esta versión de Mojarra.