0
votes

I'm using Primefaces 5.2.

On my page, I have several p:datatables with the same columns and the same sortBy expression.

Something like:

<p:dataTable .. id="tab1">
   <p:column sortBy="#{prop1}">
      #{prop1}
   </p:column>
</p:dataTable>


<p:dataTable .. id="tab2">
   <p:column sortBy="#{prop1}">
      #{prop1}
   </p:column>
</p:dataTable>

Sorting works fine so far, but I get strange behaviour and finally a NullPointerException if I sort one of the tables (let's call it table A) and then refresh the page (e.g. by firing a h:commandButton). In this case ALL tables have the same column highlighted as table A. Also, as soon as I sort a table other than table A afterwards, the following exception occurs:

21:33:36,149 SEVERE javax.enterprise.resource.webcontainer.jsf.application (default task-25) Error Rendering View[/stocks.xhtml]: java.lang.NullPointerException at org.primefaces.component.datatable.DataTable.findColumnInGroup(DataTable.java:905) [primefaces-5.2.jar:5.2] at org.primefaces.component.datatable.DataTable.findColumn(DataTable.java:896) [primefaces-5.2.jar:5.2] at org.primefaces.component.datatable.DataTable.getSortColumn(DataTable.java:1401) [primefaces-5.2.jar:5.2] at org.primefaces.component.datatable.feature.SortFeature.singleSort(SortFeature.java:136) [primefaces-5.2.jar:5.2] at org.primefaces.component.datatable.DataTableRenderer.preRender(DataTableRenderer.java:109) [primefaces-5.2.jar:5.2] at org.primefaces.component.datatable.DataTableRenderer.encodeEnd(DataTableRenderer.java:83) [primefaces-5.2.jar:5.2] at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:919) [jboss-jsf-api_2.2_spec-2.2.8.jar:2.2.8] at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1863) [jboss-jsf-api_2.2_spec-2.2.8.jar:2.2.8] at com.sun.faces.facelets.component.RepeatRenderer.encodeChildren(RepeatRenderer.java:104) [jsf-impl-2.2.8-jbossorg-1.jar:] at com.sun.faces.facelets.component.UIRepeat.process(UIRepeat.java:621) [jsf-impl-2.2.8-jbossorg-1.jar:] at com.sun.faces.facelets.component.UIRepeat.encodeChildren(UIRepeat.java:1110) [jsf-impl-2.2.8-jbossorg-1.jar:] at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1856) [jboss-jsf-api_2.2_spec-2.2.8.jar:2.2.8] at javax.faces.render.Renderer.encodeChildren(Renderer.java:176) [jboss-jsf-api_2.2_spec-2.2.8.jar:2.2.8] at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:889) [jboss-jsf-api_2.2_spec-2.2.8.jar:2.2.8] at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1856) [jboss-jsf-api_2.2_spec-2.2.8.jar:2.2.8] at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1859) [jboss-jsf-api_2.2_spec-2.2.8.jar:2.2.8] at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1859) [jboss-jsf-api_2.2_spec-2.2.8.jar:2.2.8] at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:456) [jsf-impl-2.2.8-jbossorg-1.jar:

3
Is that an ajax or non-ajax refresh? Also normally I guess you would have for example var="item" and sortBy="#{item.prop1}"Jaqen H'ghar
It's a non-ajax refresh. Yes, I have it like var="item" and sortBy="#{item.prop1}". Above is just an abbreviation.Frank

3 Answers

1
votes

The solution is to add rowStatePreserved="true" to the table containing the other tables. This was added in Primefaces 5.1.14 and is part of JSF 2.1.

Credits for: sdjavaudvk (http://forum.primefaces.org/viewtopic.php?f=3&t=43441).

<p:dataTable id="tab1" var="resumo" value="#{resumoView.resumos}" rows="20" 
                         paginator="true" 
                         rowsPerPageTemplate="5,10,15,20" 
                         rowStatePreserved="true">
...
0
votes

Have you tried using a different form for each datatable? Like this:

<h:form>
  <p:dataTable id="tab1"> ... </p:dataTable>
</h:form>
  
<h:form>
  <p:dataTable id="tab2"> ... </p:dataTable>
</h:form>
0
votes

We encountered the same problem on Primefaces6.0.

We had a form containing two tables, and a specific column can be either filtered via a list of values (filterMatchMode exact) or via an input text (filterMatchMode contains). The first table didn't have a working filter (we encountered the same NullPointerException as you did), and the second was working fine.

The two tables were in a component, and the column filtered and sorted in the two tables was built conditionnaly with the JSTL like this :

    <c:choose>
        <c:when test="#{cc.attrs.filterOperatorExact}">
            <p:column headerText="Header name"
                sortBy="#{vector.operatorForDisplay}"
                filterBy="#{vector.operatorForDisplay}" filterMatchMode="exact"
                filterOptions="#{cc.attrs.filtersOperatorList}">
                <h:outputText value="#{vector.operatorForDisplay}" />
            </p:column>
        </c:when>
        <c:otherwise>
            <p:column headerText="Header name"
                sortBy="#{vector.operatorForDisplay}"
                filterBy="#{vector.operatorForDisplay}" filterMatchMode="contains">
                <h:outputText value="#{vector.operatorForDisplay}" />
            </p:column>
        </c:otherwise>
    </c:choose>

Using the "JSF way" to do this with the rendered attribute, the problem disappeared :

    <p:column headerText="Header name"
        sortBy="#{vector.operatorForDisplay}"
        filterBy="#{vector.operatorForDisplay}" filterMatchMode="exact"
        filterOptions="#{cc.attrs.filtersOperatorList}"
        rendered="#{cc.attrs.filterOperatorExact}">
        <h:outputText value="#{vector.operatorForDisplay}"/>
    </p:column>
    <p:column headerText="Header name"
        sortBy="#{vector.operatorForDisplay}"
        filterBy="#{vector.operatorForDisplay}" filterMatchMode="contains"
        rendered="#{not cc.attrs.filterOperatorExact}">
        <h:outputText value="#{vector.operatorForDisplay}"/>
    </p:column>

Hope it helps.