2015-04-23 15 views
7

Ho aggiornato PrimeFaces dalla versione 5.1 alla 5.2 finale (la versione comunità). Ho un <p:dataTable> che viene caricato pigramente come segue (un esempio minimo per riprodurre il problema solo per scopi puramente test).java.lang.UnsupportedOperationException: getRowData (String rowKey) deve essere implementato quando non viene utilizzato l'algoritmo rowKey di base

<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> 

La corrispondente bean gestito:

@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()); 
    } 
} 

Durante la modifica del metodo onRowEdit() dovrebbe essere invocata che è legato,

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

Quando una riga è in una modalità di modifica e il link di aggiornamento contrassegnato da un segno di spunta viene cliccato, fa sì che venga generata la seguente eccezione.

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) 

Questo non dovrebbe accadere perché rowKey="#{row.fruitId}" viene utilizzato con il dato <p:dataTable>.

L'eccezione scompare solo quando l'attributo rowKey viene rimosso e i metodi getRowKey() e getRowData() vengono implementati nel bean gestito associato come segue.

@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; 
} 

E 'obbligatorio l'ultima versione di primefaces (5.2 finale), che non era necessario nella versione precedente di primefaces (5,1 finale)?

Testato su Mojarra 2.3.0-m02. Presumo che non ci dovrebbe essere alcuna rilevanza con questa versione di Mojarra.

+2

Questo sarà probabilmente ottenere rimosso come non essere formulati correttamente o anche maleducato, ecc, ma ha fatto di utilizzare qualsiasi tipo di funzionalità di ricerca e ha preso uno sguardo al forum primefaces. Discusso varie volte là nelle ultime settimane. Qualcun altro può raccogliere la reputazione per la formulazione di una risposta corretta. Edit: Scusa Tiny, solo ora vedo che è 'tu', comunque il mio commento vale il valore. Vedi http://forum.primefaces.org/viewtopic.php?f=3&t=41556 – Kukeltje

+0

Ho appena visto come dice @Kukeltje e ho trovato: 'abbiamo modificato la parte in base alla progettazione perché la gestione degli attributi rowKey con un LazyDataModel non è corretta .'. Penso che abbia perfettamente senso, non ci si può fidare di quell'id per essere completamente inizializzati in un modello dati pigro. Tuttavia, puoi fare affidamento su un listener di azioni che lo carica dal controller quando richiesto. Ecco il thread: http://forum.primefaces.org/viewtopic.php?f=3&t=41556 –

+0

Questa volta, sono in ritardo per aggiornare PrimeFaces e non posso usare i suoi candidati rilasciati, poiché la mia applicazione è fortemente dipendente su PrimeFaces Extensions la cui versione finale è stata rilasciata solo poche ore fa da oggi. Ciò richiede ora la regolazione del codice in più punti. – Tiny

risposta

5

Come accennato in this link che punta alla Community Forum primefaces,

Abbiamo cambiato che parte dalla progettazione causare la movimentazione con un attributo LazyDataModelrowKey non è corretto.

Questi due metodi getRowKey() e getRowData() devono essere attuate nel bean gestito associato quando viene utilizzato LazyDataModel<T> come mostrato in questione.

Da PrimeFaces User Guide (PDF) - (5.1 (pagina 164) e 5.2 (pagina 166)):

caricamento pigro è un approccio a che fare con enormi set di dati in modo efficiente, lavori di impaginazione basate regolare ajax per il rendering solo una particolare ma richiede comunque che tutti i dati vengano caricati in memoria. Lazy caricamento dati visualizzabile una pagina particolare allo stesso modo, ma anche solo carica i dati della pagina in memoria, non l'intero set di dati. Per implementare questo metodo, è necessario eseguire il binding di un valore org.primefaces.model.LazyDataModel come valore e implementare il metodo di caricamento e abilitare l'opzione lazy. Inoltre è necessario implementare getRowData e getRowKey se la selezione è abilitata.


L'attributo rowKey possono essere utilizzati, quando lazy è disabilitato - è impostato false (default) e selezione di riga viene abilitata.

Da PrimeFaces User Guide (PDF) - (5.1 (pagina 159) e 5.2 (pagina 161)):

RowKey dovrebbe un identificatore univoco dal vostro modello di dati e utilizzato da DataTable per trovare le righe selezionate. È possibile definire questa chiave per utilizzando l'attributo rowKey o associando un modello di dati che implementa org.primefaces.model.SelectableDataModel.

Come ad esempio,

<p:dataTable var="car" 
      value="#{carBean.cars}" 
      selection="#{carBean.selectedCars}" 
      rowKey="#{car.id}"> 

    <p:column selectionMode="multiple"/> 
    <!--columns--> 
</p:dataTable> 
Problemi correlati