Spring Data PageImpl not returning page with correct size?

I am trying to create a new Page using a list of objects retrieved from the database. First, I get all the elements from the database, convert them to a stream, and then use lambda to filter the results. Then I need a page with a given number of elements, however creating a new PageImpl does not return a page with the correct size.

Here is my code:

 List<Produtos> listaFinal; Stream<Produtos> stream = produtosRepository.findAll().stream(); listaFinal = stream.filter(p -> p.getProdNome().contains("uio")).collect(Collectors.toList()); long total = listaFinal.size(); Page<Produtos> imp = new PageImpl<>(listaFinal,pageable,total); 

Here is a debug screenshot:

Notice that the size in the Pageable is set to 20, and he understands that he needs 4 pages to render 70 elements, but he returns the whole list.

What am I missing?

Edit response to comment made by Thomas:

I understand how to use the page to return the entire piece of data. The code I showed was my attempt to use a lambda expression to filter my collection. The problem for me is that I want to use Java 8 lambda to query a database through Spring Data JPA. I used expressions for VB.NET and Entity function(x) queries and wondered how to do the same with Spring JPA.

In my repository I use extends JpaRepository<Produtos, Integer>, QueryDslPredicateExecutor<Produtos> , which gives me access to findAll(Predicate,Pageable) . However, the predicate is not typed, so I can’t just use p -> p.getProdNome().contains("uio") in the request. I am using SQL Server and Hibernate.

+5
source share
4 answers

After learning more about how Spring Data works, I ended up using @Query annotations for my methods inside JpaRepository implementations to properly query the database and filter the results, eliminating the need to use a stream and then converting back to Page.

Here is what the code above would look like if someone needed an example:

 @Query("select p from Produtos p where p.prodNome = ?1") public Page<Produtos> productsListByName(String prodNome, Pageable pageable) 

I am aware of Spring findBy methods, but sometimes method names become very difficult to read depending on the number of parameters, so I just stuck with JPQL.

This way, the content of the page will always contain the maximum number of elements that you define in the Spring configuration.

I also use the custom implementation of PageImpl , I don’t work right now and don’t have access to the code, but I will publish it when I can.

Edit: custom implementation can be found here

+4
source

If I understand your code correctly, then you intend to download all the records from the database and split them into x buckets that are collected in PageImpl , right?

The way it worked. The actual intent of the Pageable and Page abstractions is NOT to request all the data, but simply to “slice” the data that is needed.

In your case, you can request data through Page<X> page = repository.findAll(pageable); and just return it. The page contains entries for the current page along with some additional information, such as the total number of entries and whether there is a next page.

In your client code, you can use this information to render a list of records and properly create the next / previous links. Please note that a query with Page<X> as a result type produces 2 queries (1 for determining the total total number of queries and 1 for the actual page data).

If you do not need information about the total number of results, but still you want to create the following link, you should use Slice<X> as the return type - since it issues only 1 request.

+2
source

PageImpl not intended to perform any pagination on your list. From the docs, you can see that this is just a “basic Page implementation” that almost sounds the way you want, but it is really misleading.

Use the PagedListHolder , which is a simple state holder for processing lists of objects, dividing them into pages.

+2
source

To extend the response of stites , PagedListHolder is the way to go and here is how:

 List<String> list = // ... // Creation PagedListHolder page = new PagedListHolder(list); page.setPageSize(10); // number of items per page page.setPage(0); // set to first page // Retrieval page.getPageCount(); // number of pages page.getPageList(); // a List which represents the current page 

If you need sorting, use another PagedListHolder constructor with MutableSortDefinition .

0
source

Source: https://habr.com/ru/post/1206108/


All Articles