1
votes

I have a Primefaces DataTable inside an AccordionPanel with dynamic number of tabs. The DataTable can be sorted by each column by click on the column header. The DataTable throws an NullPointerException in Primefaces' DataTable class when updating a row. The error occurs only after the table has been sorted before. I've tested the same table outside the accordion, and it does not show the error.

What am I doing wrong ?

My xhtml:

<ui:define name="content">
    <h:form id="contentForm">

      <p:accordionPanel id="wearDataAccordion" value="#{wearDataBean.wearDataTypes}" var="type" multiple="true">
        <p:tab title="#{wearDataBean.getAggregateTypeLabel(type)}">

          <p:dataTable width="100%" var="wearData" value="#{wearDataBean.getWearData(type)}" sortBy="#{wearData.aggregate.sequence}" sortOrder="ASCENDING" 
                       scrollable="false" rowStyleClass="" styleClass="" emptyMessage="#{messages['lbl.no.data']}">

            <p:column headerText="#{messages['lbl.weardata.label']}" sortBy="#{wearData.aggregate.sequence}" width="15%">
              <p:outputLabel value="#{wearData.label}"/>
            </p:column>

            <p:column styleClass="column-numerical-right" headerText="#{messages['lbl.weardata.value']}" 
                                              sortBy="#{wearDataBean.getValue(wearData)}" width="5%">
              <p:outputLabel value="#{wearDataBean.getValue(wearData)}" style="float:right"/>
            </p:column>

            <p:column headerText="#{messages['lbl.weardata.unit']}" sortBy="#{wearData.unitId}" width="10%">
              <p:outputLabel value="#{wearDataBean.getUnitLabel(wearData.unitId)}"/>
            </p:column>

            <p:column headerText="#{messages['lbl.weardata.lastUpdate']}" sortBy="#{wearData.lastUpdate}" width="20%">
              <p:outputLabel value="#{wearData.lastUpdate}">
                <f:convertDateTime dateStyle="medium" timeStyle="medium" type="both" timeZone="#{localeData.timeZoneId}"/>
              </p:outputLabel>
            </p:column>  

            <p:column styleClass="column-button-icon" headerText="#{messages['lbl.dest.actions']}" width="7%">
              <eae:commandButton icon="/resources/images/ui_content_dest_service.svg" styleClass="" svgStyleClass="ui-svg-button-icon-only-svg-size" 
                                                title="#{messages['lbl.weardata.reset']}" action="#{wearDataBean.reset(wearData)}" global="false">
                <p:confirm header="#{messages['lbl.weardata.reset']}" message="#{messages['lbl.weardata.confirm.question']}" icon="ui-icon-alert" />
              </eae:commandButton>
            </p:column>

          </p:dataTable>

        </p:tab>
      </p:accordionPanel>


      <p:remoteCommand name="updateBean" actionListener="#{wearDataBean.updateData()}" global="false"/>
    </h:form>

    <p:socket onMessage="handleWearDataMessage" channel="#{messagePublisher.wearDataUpdateChannelName}"/>
    <script type="text/javascript">
      function handleWearDataMessage(data) {
        var jsonString = JSON.stringify(data);
        updateBean([{name: 'data', value: jsonString}]);
      }
    </script>

  </ui:define>

The exception it throws is:

13:20:47,060 [SEVERE] [org.primefaces.application.exceptionhandler.PrimeExceptionHandler] (default task-7) null: java.lang.NullPointerException
   at org.primefaces.component.datatable.DataTable.findColumnInGroup(DataTable.java:903) [primefaces-5.1.14.jar:5.1.14]
   at org.primefaces.component.datatable.DataTable.findColumn(DataTable.java:894) [primefaces-5.1.14.jar:5.1.14]
   at org.primefaces.component.datatable.DataTable.getSortColumn(DataTable.java:1401) [primefaces-5.1.14.jar:5.1.14]
   at org.primefaces.component.datatable.feature.SortFeature.singleSort(SortFeature.java:136) [primefaces-5.1.14.jar:5.1.14]
   at org.primefaces.component.datatable.DataTableRenderer.preRender(DataTableRenderer.java:109) [primefaces-5.1.14.jar:5.1.14]
   at org.primefaces.component.datatable.DataTableRenderer.encodeEnd(DataTableRenderer.java:83) [primefaces-5.1.14.jar:5.1.14]
   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 javax.faces.component.UIComponent.encodeAll(UIComponent.java:1859) [jboss-jsf-api_2.2_spec-2.2.8.jar:2.2.8]
   at org.primefaces.component.accordionpanel.AccordionPanelRenderer.encodeTab(AccordionPanelRenderer.java:226) [primefaces-5.1.14.jar:5.1.14]
   at org.primefaces.component.accordionpanel.AccordionPanelRenderer.encodeTabs(AccordionPanelRenderer.java:171) [primefaces-5.1.14.jar:5.1.14]
   at org.primefaces.component.accordionpanel.AccordionPanelRenderer.encodeMarkup(AccordionPanelRenderer.java:103) [primefaces-5.1.14.jar:5.1.14]
   at org.primefaces.component.accordionpanel.AccordionPanelRenderer.encodeEnd(AccordionPanelRenderer.java:76) [primefaces-5.1.14.jar:5.1.14]
   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.context.PartialViewContextImpl$PhaseAwareVisitCallback.visit(PartialViewContextImpl.java:582) [jsf-impl-2.2.8-jbossorg-1.jar:]
   at com.sun.faces.component.visit.PartialVisitContext.invokeVisitCallback(PartialVisitContext.java:183) [jsf-impl-2.2.8-jbossorg-1.jar:]
   at org.primefaces.component.api.UITabPanel.visitTree(UITabPanel.java:948) [primefaces-5.1.14.jar:5.1.14]
   at javax.faces.component.UIComponent.visitTree(UIComponent.java:1700) [jboss-jsf-api_2.2_spec-2.2.8.jar:2.2.8]
   at javax.faces.component.UIForm.visitTree(UIForm.java:371) [jboss-jsf-api_2.2_spec-2.2.8.jar:2.2.8]
   at javax.faces.component.UIComponent.visitTree(UIComponent.java:1700) [jboss-jsf-api_2.2_spec-2.2.8.jar:2.2.8]
   at javax.faces.component.UIComponent.visitTree(UIComponent.java:1700) [jboss-jsf-api_2.2_spec-2.2.8.jar:2.2.8]
   at javax.faces.component.UIComponent.visitTree(UIComponent.java:1700) [jboss-jsf-api_2.2_spec-2.2.8.jar:2.2.8]
   at com.sun.faces.context.PartialViewContextImpl.processComponents(PartialViewContextImpl.java:403) [jsf-impl-2.2.8-jbossorg-1.jar:]
   at com.sun.faces.context.PartialViewContextImpl.processPartial(PartialViewContextImpl.java:322) [jsf-impl-2.2.8-jbossorg-1.jar:]
   at org.primefaces.context.PrimePartialViewContext.processPartial(PrimePartialViewContext.java:60) [primefaces-5.1.14.jar:5.1.14]
   at javax.faces.context.PartialViewContextWrapper.processPartial(PartialViewContextWrapper.java:219) [jboss-jsf-api_2.2_spec-2.2.8.jar:2.2.8]
   at javax.faces.component.UIViewRoot.encodeChildren(UIViewRoot.java:1004) [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 com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:430) [jsf-impl-2.2.8-jbossorg-1.jar:]
   at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:133) [jsf-impl-2.2.8-jbossorg-1.jar:]
   at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:337) [jboss-jsf-api_2.2_spec-2.2.8.jar:2.2.8]
   at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:337) [jboss-jsf-api_2.2_spec-2.2.8.jar:2.2.8]
   at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:337) [jboss-jsf-api_2.2_spec-2.2.8.jar:2.2.8]
   at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:120) [jsf-impl-2.2.8-jbossorg-1.jar:]
   at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101) [jsf-impl-2.2.8-jbossorg-1.jar:]
   at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:219) [jsf-impl-2.2.8-jbossorg-1.jar:]
   at javax.faces.webapp.FacesServlet.service(FacesServlet.java:647) [jboss-jsf-api_2.2_spec-2.2.8.jar:2.2.8]
   at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:85) [undertow-servlet-1.1.0.Final.jar:1.1.0.Final]
   at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:130) [undertow-servlet-1.1.0.Final.jar:1.1.0.Final]
   at io.undertow.websockets.jsr.JsrWebSocketFilter.doFilter(JsrWebSocketFilter.java:129) [undertow-websockets-jsr-1.1.0.Final.jar:1.1.0.Final]
   at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:60) [undertow-servlet-1.1.0.Final.jar:1.1.0.Final]
   at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:132) [undertow-servlet-1.1.0.Final.jar:1.1.0.Final]
   at io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:85) [undertow-servlet-1.1.0.Final.jar:1.1.0.Final]
   at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:61) [undertow-servlet-1.1.0.Final.jar:1.1.0.Final]
   at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36) [undertow-servlet-1.1.0.Final.jar:1.1.0.Final]
   at org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78)
   at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) [undertow-core-1.1.0.Final.jar:1.1.0.Final]
   at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:131) [undertow-servlet-1.1.0.Final.jar:1.1.0.Final]
   at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:56) [undertow-servlet-1.1.0.Final.jar:1.1.0.Final]
   at io.undertow.server.handlers.DisableCacheHandler.handleRequest(DisableCacheHandler.java:33) [undertow-core-1.1.0.Final.jar:1.1.0.Final]
   at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) [undertow-core-1.1.0.Final.jar:1.1.0.Final]
   at io.undertow.security.handlers.AuthenticationConstraintHandler.handleRequest(AuthenticationConstraintHandler.java:51) [undertow-core-1.1.0.Final.jar:1.1.0.Final]
   at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:45) [undertow-core-1.1.0.Final.jar:1.1.0.Final]
   at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:63) [undertow-servlet-1.1.0.Final.jar:1.1.0.Final]
   at io.undertow.servlet.handlers.security.ServletSecurityConstraintHandler.handleRequest(ServletSecurityConstraintHandler.java:56) [undertow-servlet-1.1.0.Final.jar:1.1.0.Final]
   at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:58) [undertow-core-1.1.0.Final.jar:1.1.0.Final]
   at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:70) [undertow-servlet-1.1.0.Final.jar:1.1.0.Final]
   at io.undertow.security.handlers.SecurityInitialHandler.handleRequest(SecurityInitialHandler.java:76) [undertow-core-1.1.0.Final.jar:1.1.0.Final]
   at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) [undertow-core-1.1.0.Final.jar:1.1.0.Final]
   at org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61)
   at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) [undertow-core-1.1.0.Final.jar:1.1.0.Final]
   at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) [undertow-core-1.1.0.Final.jar:1.1.0.Final]
   at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:261) [undertow-servlet-1.1.0.Final.jar:1.1.0.Final]
   at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:247) [undertow-servlet-1.1.0.Final.jar:1.1.0.Final]
   at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:76) [undertow-servlet-1.1.0.Final.jar:1.1.0.Final]
   at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:166) [undertow-servlet-1.1.0.Final.jar:1.1.0.Final]
   at io.undertow.server.Connectors.executeRootHandler(Connectors.java:197) [undertow-core-1.1.0.Final.jar:1.1.0.Final]
   at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:759) [undertow-core-1.1.0.Final.jar:1.1.0.Final]
   at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [rt.jar:1.7.0_67]
   at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [rt.jar:1.7.0_67]
   at java.lang.Thread.run(Thread.java:745) [rt.jar:1.7.0_67]

The updateData() method from the backing bean is as following:

 /**
   * Refreshes the data within this bean 
   */
  public void updateData() {
    this.logger.debug("Ajax listener method for wearDataUpdate called!");

    // do update data
    boolean refreshAll = false;
    boolean refresh    = false;
    UpdateEvent<Integer> updateEvent = this.extractRequestData(new TypeToken<UpdateEvent<Integer>>() { /* ignored */ }.getType(), "data");
    if (updateEvent.getType().equals(Type.CREATE)) {
      refresh |= this.addWearDataToDomainData(updateEvent.getData());
    } else if (updateEvent.getType().equals(Type.DELETE)) {
      refresh |= this.removeWearDataFromDomainData(updateEvent.getData());
    } else {
      refreshAll = true;
    }

    // delete old data if refresh all is set
    if (refreshAll) {
      this.wearDataListsByType = null;
    }

    // update table in view
    if (refresh || refreshAll) {
      Ajax.update("contentForm:wearDataAccordion");
    }
  }

PrimeFaces 5.1.14, Omnifaces 2.0, WildFly 8.2.0

2
primefaces-5.1.14.jar != 5.3.4 ???Kukeltje
Yes you are right, sorry... we're using 5.1.14. I've changed it in the original post.Frank Leuband

2 Answers

1
votes

The solution is to use widgetVar="data" inside datatable. Is necessary to Javascript recognize this ID.

<p:dataTable width="100%" var="wearData" value="#{wearDataBean.getWearData(type)}" sortBy="#{wearData.aggregate.sequence}" sortOrder="ASCENDING" 
                   scrollable="false" rowStyleClass="" styleClass="" emptyMessage="#{messages['lbl.no.data']}" widgetVar="data">

Intro To PrimeFaces widgetVar

1
votes

I had the same problem regarding the sorting of datatables dynamically generated in tabs from accordionPanel and the widgetVar solution didn't fix my issue.

The solution that made the sorting work was to include a p:columnGroup(not so useful besides making things work)

<p:columnGroup type="header">
    <p:row>
        <p:column headerText="Column 1">...</p:column>
        ...
    </p:row>
</p:columnGroup>