go to page with FilterablePageableDataProvider

Hello,

my intention is to display data in a grid with a fixed no. of rows and paging.
I’m using spring boot with jpa in the backend.
The Backend service that supplies the data looks like:

public Page<SOULPatch> findAnyMatching(SOULPatchesGridDataProvider.SOULPatchFilter filter, Pageable pageable)
public public int countAnyMatching(SOULPatchesGridDataProvider.SOULPatchFilter filter)

I created a dataprovider similar to the one I found in the bakery starter app.
Now I have the problem, that I don’t know how to tell the data provider to load a specific page, how to setup the page size. If I set the page size of the grid using the data provider to some number, then for a split second after loading I see the correct number in the grid (and in the log), but for some reason it reloads all data from the backend, but this time with a page size, such that everything is in one page (tested with 107 entries).

My DataProvider:

@SpringComponent
@UIScope
public class SOULPatchesGridDataProvider
        extends FilterablePageableDataProvider<SOULPatch, SOULPatchesGridDataProvider.SOULPatchFilter>
        implements HasLogger {

    private static final long serialVersionUID = 8027534129208314189L;

    private final SOULPatchService soulPatchService;
    private List<QuerySortOrder> defaultSortOrders;
    private Consumer<Page<SOULPatch>> pageObserver;

    public SOULPatchesGridDataProvider(@Autowired SOULPatchService soulPatchService) {
        this.soulPatchService = soulPatchService;
        setSortOrders(UIConst.DEFAULT_SORT_DIRECTION, UIConst.ORDER_SORT_FIELDS_SOULPATCHES);
    }

    public void setSortOrders(Sort.Direction direction, String[] properties) {
        QuerySortOrderBuilder builder = new QuerySortOrderBuilder();
        for (String property : properties) {
            if (direction.isAscending()) {
                builder.thenAsc(property);
            } else {
                builder.thenDesc(property);
            }
        }
        defaultSortOrders = builder.build();
    }

    @Override
    protected Page<SOULPatch> fetchFromBackEnd(
            Query<SOULPatch, SOULPatchFilter> query, Pageable pageable) {
        SOULPatchFilter filter = query.getFilter().orElse(SOULPatchFilter.getEmptyFilter());
        Page<SOULPatch> page = soulPatchService.findAnyMatching(filter, pageable);
        if (pageObserver != null) {
            pageObserver.accept(page);
        }
        LOGGER().debug("query: {} pageable: {} result: {}", query, pageable, page);
        return page;
    }

    @Override
    protected List<QuerySortOrder> getDefaultSortOrders() {
        return defaultSortOrders;
    }

    @Override
    protected int sizeInBackEnd(Query<SOULPatch, SOULPatchFilter> query) {
        SOULPatchFilter filter = query.getFilter().orElse(SOULPatchFilter.getEmptyFilter());
        int count = soulPatchService.countAnyMatching(filter);
        LOGGER().debug("size in backend for query {}: {}", query, count);
        return count;
    }

    public void setPageObserver(Consumer<Page<SOULPatch>> pageObserver) {
        this.pageObserver = pageObserver;
    }

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @EqualsAndHashCode
    @ToString
    public static class SOULPatchFilter implements Serializable {
        private static final long serialVersionUID = -2667841574926699231L;
        private Set<AppUser> userFilter = new HashSet<>();
        private Optional<String> namesFilter = Optional.empty();

        public static SOULPatchFilter getEmptyFilter() {
            return new SOULPatchFilter();
        }
    }
}
// I add the dataprovider to the grid via
grid.setDataProvider(dataProvider);
// ...
// I try to set the page size like this
grid.setPageSize(3);

Initially the correct number of entries is fetched from the backend → OK
The page observer gets informed about how many pages there are gonna be overall → OK
But then the grid or dataprovider automatically fetches from the backend again → :frowning:
Ignoring the set page size everything in one page → :frowning:

What I was looking for is something like pageProvider.goto(Pageable page)

How can I set the page size and control the page to fetch for?

I didn’t exactly figure out what exactly was going on before, but using a PaginatedGrid together with the DataProvider above works.

<groupId>org.vaadin.klaudeta</groupId>
<artifactId>grid-pagination</artifactId>

The PaginatedGrid uses an inner class

private class InnerQuery<F> extends Query<T, F> {

	InnerQuery() {
	    this(0);
	}

	InnerQuery(int offset) {
	    super(offset, getPageSize(), getDataCommunicator().getBackEndSorting(), getDataCommunicator().getInMemorySorting(), null);
	}

	InnerQuery(int offset, List<QuerySortOrder> sortOrders, SerializableComparator<T> serializableComparator) {
	    super(offset, getPageSize(), sortOrders, serializableComparator, null);
	}

}

and fetches the page via:

private void doCalcs(int newPage) {
	int offset = newPage > 0 ? (newPage - 1) * this.getPageSize() : 0;

	InnerQuery query = new InnerQuery<>(offset);

	pagination.setTotal(dataProvider.size(query));

	super.setDataProvider(DataProvider.fromStream(dataProvider.fetch(query)));

}