2015-04-23 44 views
7

Mam zaktualizowane PrimeFaces z 5.1 końcowego do 5.2 końcowego (wydanie społecznościowe). Mam <p:dataTable>, który jest leniwie ładowany w następujący sposób (minimalny przykład, aby odtworzyć problem wyłącznie w celu czystego testowania).java.lang.UnsupportedOperationException: getRowData (String rowKey) musi być zaimplementowana, gdy podstawowy algorytm rowKey nie jest używany

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

Odpowiedni udało fasola:

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

Podczas edycji metodę onRowEdit() ma zostać wywołany, który jest związany,

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

Kiedy rząd jest w trybie edycji i link aktualizacji zaznaczony przez kliknięcie powoduje wygenerowanie następującego wyjątku.

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) 

To nie powinno się zdarzyć, ponieważ rowKey="#{row.fruitId}" jest używany z danym <p:dataTable>.

Wyjątek znika tylko wtedy, gdy atrybut rowKey został usunięty, a metody getRowKey() i zostały zaimplementowane w powiązanym zarządzanym komponencie bean w następujący sposób.

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

Czy jest obowiązkowe w najnowszej wersji (5.2 PrimeFaces ostateczna), która nie była potrzebna w poprzedniej wersji PrimeFaces (5.1 final)?

Testowany na Mojarrze 2.3.0-m02. Przypuszczałem, że nie powinno być żadnego związku z tą wersją Mojarry.

+2

To będzie prawdopodobnie zostaną usunięte jako nie sformułowane poprawnie lub nawet niegrzeczny itp, ale nie używać jakichkolwiek funkcji wyszukiwania i przyjrzał się forum PrimeFaces. Kilka razy omawiano tam ostatnie tygodnie. Ktoś inny może zebrać reputację, by sformułować poprawną odpowiedź. Edycja: Przepraszam Tiny, dopiero teraz widzę, że to "ty", ale mój komentarz ma wartość. Zobacz http://forum.primefaces.org/viewtopic.php?f=3&t=41556 – Kukeltje

+0

Po prostu wyglądało jak @Kukeltje mówi i stwierdził: 'zmieniliśmy tę część według projektu, ponieważ obsługa atrybutów rowKey z LazyDataModel jest nieprawidłowa . ". Myślę, że to ma sens, nie można ufać, że id jest w pełni zainicjowany w leniwym modelu danych. Można jednak polegać na detektorze działań, który załaduje go ze sterownika, gdy będzie żądany. Tutaj jest wątek: http://forum.primefaces.org/viewtopic.php?f=3&t=41556 –

+0

Tym razem jestem już za późno, aby zaktualizować PrimeFaces i nie mogłem użyć zwolnionych kandydatów, ponieważ moja aplikacja jest bardzo zależna w przypadku rozszerzeń PrimeFaces, których ostateczna wersja została wydana zaledwie kilka godzin temu. Wymaga to teraz dostosowania kodu w kilku miejscach. – Tiny

Odpowiedz

5

Jak wspomniano w this link wskazujący na PrimeFaces Community Forum

Zmieniliśmy że część z projektem powodować atrybut rowKey obsługi z LazyDataModel nie jest poprawna.

Te dwie metody getRowKey() i getRowData() muszą być realizowane w odpowiedniej udało fasoli, gdy stosuje się LazyDataModel<T> jak pokazano w pytaniu.

Od PrimeFaces User Guide (PDF) - (5,1 (strona 164) i 5.2 (strona 166)):

Lazy Loading to podejście do czynienia z ogromnymi zbiorami danych efektywnie regularne ajax oparte prace paginacji przez pełnienie jedynie szczególności strona, ale nadal wymaga załadowania wszystkich danych do pamięci. Lazy ładowanie datatable renderuje konkretną stronę podobnie, ale także tylko ładuje dane strony do pamięci, a nie całego zbioru danych. Aby to wykonać, musisz powiązać wartość org.primefaces.model.LazyDataModel i zaimplementować metodę obciążenia i włączyć opcję opóźnienia. Wymagane jest również wdrożenie getRowData i getRowKey, jeśli wybrano opcję włączoną.


atrybut rowKey mogą być stosowane, gdy jest wyłączona lazy - została false (domyślnie) i selekcji wiersza jest włączone.

Od PrimeFaces User Guide (PDF) - (5,1 (strona 159) i 5.2 (strona 161)):

RowKey powinny unikalny identyfikator z modelu danych i wykorzystywane przez DataTable znaleźć wybrane wiersze. Możesz zdefiniować ten klucz przez za pomocą atrybutu rowKey lub przez powiązanie modelu danych, który implementuje org.primefaces.model.SelectableDataModel.

Takich jak

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

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