0

I am using PrimeFaces <p:dataTable> with pagination. I use <h:selectBooleancheckbox> with a Map property for corresponding row selection. The problem which I am facing is when I select and submit the values, there is a NullPointerException. The values are checked for particular rows only. I am using JSF 2.0 and PrimeFaces 3.0.

My page is:

<p:dataTable id="ngoPhotoTab" paginator="true" rows="10" value="#  {photoApprovelBean.lstNgoPhotos}" var="ngoPhoto">
    <p:column headerText="NgoName">
        #{ngoPhoto.ngoName}
    </p:column>
    <p:column headerText="Select">
        <h:selectBooleanCheckbox id="ngoSelect" layout="pageDirection" value="#{photoApprovelBean.checked[ngoPhoto.photo_id]}" />
    </p:column>
    <f:facet name="footer"> 
        <p:commandButton onclick="deletePhoto();" value="Delete" />
    </f:facet>
</p:dataTable>

Backing bean logic:

public class PhotoApprovelBean {

    public String deleteActPhoto() {
        List checkedItems = new ArrayList();

        try {
            for (Iterator<PhotoApprovelBean> itr = disAppPhotoList.iterator(); itr.hasNext();) {
                PhotoApprovelBean item = (PhotoApprovelBean) itr.next();

                if (checked.get(item.getPhotoId())) {
                    checkedItems.add(item.getPhotoId());
                }
            }

            toDeletePhoto(checkedItems);
        }catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    public Map<Long, Boolean> checked = new HashMap<Long, Boolean>();

    public Map<Long, Boolean> getChecked() {
        return checked;
    }
}

The NullPointerException is caused in the line if (checked.get(item.getPhotoId())). The The Map is filled with values of first page only. How is this caused and how can I solve it?

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
Muthu
  • 269
  • 3
  • 9
  • 23

1 Answers1

4

You got a NullPointerException, because the if statement expects a boolean, but the Map contains Boolean values only which can possibly be null. They will be null for other pages. The Boolean value of null can't be autoboxed to a boolean. You'd need to add a nullcheck.

Boolean itemChecked = checked.get(item.getPhotoId());

if (itemChecked != null && itemChecked) {
    // ...
}

Better, however, is to use PrimeFaces own <p:column selectionMode="multiple"> instead. It will remember the selection on other pages. The Map approach is only suitable if you don't use pagination. See also the showcase example. Here's how it can look like for you:

<p:dataTable id="ngoPhotoTab" paginator="true" rows="10" 
    value="#{photoApprovelBean.lstNgoPhotos}" var="ngoPhoto"
    selection="#{photoApprovelBean.selectedNgoPhotos}" rowKey="#{ngoPhoto.photoId}"
>
    <p:column headerText="NgoName">
        #{ngoPhoto.ngoName}
    </p:column>
    <p:column headerText="Select" selectionMode="multiple" />
    <f:facet name="footer"> 
        <p:commandButton onclick="deletePhoto();" value="Delete" />
    </f:facet>
</p:dataTable>

with

private PhotoApprovelBean[] selectedNgoPhotos;
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555