I get a Page from my database through JpaRepository and want to filter this page by name.
This is my code:
// other code
Pageable pageable = PageRequest.of(page,size);
Page<Entity> foundEntities = entityRepository.findAll(pageable);
final String compareString = "example";
List<Entity> filteredEntities = foundEntities
.stream()
.filter(e -> e.getName().toLowerCase().contains(compareString))
.collect(Collectors.toList());
foundEntities = new PageImpl<>(filteredEntities, pageable, filteredEntities.size());
//other code
The filtering works and I only get the entities, that contain the compareString, but the paging doesn't work and I only get a single list of entities. When I don't use the filter the paging works correctly.
In my opinion, you should be leaving that task to your database and not trying to handle it in your own code. Your code will be easier to maintain and much more efficient as your database engine will be able to filter by orders of magnitude faster than any Java code.
It looks like you're using Spring Data JPA, you can achieve this by simply declaring the following method in your repository.
Page<Entity> findAllByNameContaining(String name, Pageable pageable);
Calling that method will return a Page
of Entity
that have already been filtered via the query.
First of all, I think it is better to use PagingAndSortingRepository instead of filtering in the controller method.
public interface VideoRepository extends PagingAndSortingRepository<Video, Integer>
{
Page<Video> findAllByCategory(String aInCategory, Pageable aInPageable);
}
Then use this method from a specific service. For example.
@Override
public Page<Video> browseVideosByCategory(String aInCategory, int page, int size)
{
return videoRepository.findAllByCategory(aInCategory, PageRequest.of(page, size));
}
For the error in your code, make sure that you are incrementing the page value. Could you add the Controller arguments and web page?
For example, the page can be incremented by a click on the page's number that contains a link to the following controller.
@GetMapping("/getVideoByCategory/{category}")
public String getVideoByCategory(Model model, @PathVariable String category, @RequestParam(name = "page", defaultValue = "0") int page,
@RequestParam(name = "size", defaultValue = "4") int size) {
Page<Video> videos = videoService.browseVideosByCategory(category, page, size);
int[] pages = new int[videos.getTotalPages()];
model.addAttribute("pages", pages);
model.addAttribute("category", category);
model.addAttribute("videos", videos.getContent());
return "videoViewWithCategory";
}
The number of the pages is added to the module.
At last, in the html page. Add a link on the number of page containing the information (number of page and Category which is name in your case). Thymeleaf is used in this example.
<li th:each="p, status:${pages}">
<a th:href="@{/getVideoByCategory/{category}(category=${category},page = ${status.index} )}" th:text="${status.index}"></a>
</li>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With