primefaces: DataTable: lazy loading pagination error

I’ve detected an issue related to pagination when using lazy loading in datatable. The problem is the following: starting by the example of showcase: http://www.primefaces.org/showcase/ui/data/datatable/lazy.xhtml, if we add a button to delete the records one by one, if you are for instance in page 2, when all record of this page have been deleted, the pagination “brokes” and displays page 1 with empty data.

Assume that the button “Delete” calls a method called “deleteCar(Car car)” which deletes the car object from the list (or directly from database), and then update the datatable, firing again the load() method from LazyDatamodel.

<p:dataTable var="car" value="#{dtLazyView.lazyModel}" paginator="true" rows="10"
                 paginatorTemplate="{RowsPerPageDropdown} {FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink}"
                 rowsPerPageTemplate="5,10,15" selectionMode="single" selection="#{dtLazyView.selectedCar}" id="carTable" lazy="true">
        <p:ajax event="rowSelect" listener="#{dtLazyView.onRowSelect}" update=":form:carDetail" oncomplete="PF('carDialog').show()" />
        <p:column headerText="Id" sortBy="#{car.id}" filterBy="#{car.id}">
            <h:outputText value="#{car.id}" />
        </p:column>
        <p:column headerText="Year" sortBy="#{car.year}" filterBy="#{car.year}">
            <h:outputText value="#{car.year}" />
        </p:column>
        <p:column headerText="Brand" sortBy="#{car.brand}" filterBy="#{car.brand}">
            <h:outputText value="#{car.brand}" />
        </p:column>
        <p:column headerText="Color" sortBy="#{car.color}" filterBy="#{car.color}">
            <h:outputText value="#{car.color}" />
        </p:column>
<p:column headerText="Color" sortBy="#{car.color}" filterBy="#{car.color}">
            <p:commandButton value="Delete" action="#{dtLazyView.deleteCar(car)}" update="carTable">
</p:commandButton>
        </p:column>
    </p:dataTable>

In the example, an IndexOutOfBoundsException will be also thrown, when deleting the last record of page 2, variable “first” will pass a value of 10 (assuming rows per page is 10) and a subList from 10 to 10-1…

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 2
  • Comments: 36 (36 by maintainers)

Commits related to this issue

Most upvoted comments

Not sure if it fixes your problem but i always ´do something like this in my AbstractLazyDataModel:

`    @Override
    public List<T> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, Object> filters)
    {
        long rowCount = do your select count with filters included
        setRowCount(rowCount);
        
        if (rowCount  > 0 && first >= rowCount) {
            int numberOfPages = (int) Math.ceil(rowCount * 1d / pageSize);
            first = Math.max((numberOfPages - 1) * pageSize, 0);
        }

        .....

Not mandatory but to avoid another long debate, just make it abstract, and i’ll simply return getRowCount in our impls.

Figured out how to break it. Integrationtest ist updated. Ready to get fixed. 😉

I’ll add a test later this week.

Ok I reproduced the issue in lazy mode (didn’t try in default mode): delete all rows of the last page the paginator updates with page 19 of 19 but no rows are displayed.