Creating Pagination in Spring Data JPA - java

I am trying to implement pagination feature in Spring Data JPA.
I am referring this Blog
My Controller contains following code :
#RequestMapping(value="/organizationData", method = RequestMethod.GET)
public String list(Pageable pageable, Model model){
Page<Organization> members = this.OrganizationRepository.findAll(pageable);
model.addAttribute("members", members.getContent());
float nrOfPages = members.getTotalPages();
model.addAttribute("maxPages", nrOfPages);
return "members/list";
}
My DAO is following :
#Query(value="select m from Member m", countQuery="select count(m) from Member m")
Page<Organization> findMembers(Pageable pageable);
I am able to show first 20 records, how do I show next 20???
Is there any other pagination example that I can refer??

The constructors of Pageable are deprecated, use of() instead:
Pageable pageable = PageRequest.of(0, 20);

I've seen similar problem last week, but can't find it so I'll answer directly.
Your problem is that you specify the parameters too late. Pageable works the following way: you create Pageable object with certain properties. You can at least specify:
Page size,
Page number,
Sorting.
So let's assume that we have:
PageRequest p = new PageRequest(2, 20);
the above passed to the query will filter the results so only results from 21th to 40th will be returned.
You don't apply Pageable on result. You pass it with the query.
Edit:
Constructors of PageRequest are deprecated. Use Pageable pageable = PageRequest.of(2, 20);

Pageable object by default comes with size 20, page 0, and unsorted
So if you want the next page in front end the url can be sent with query params page, size,sort and these u can test it on postman.

You can use Page, List or Slice.
If you dont need the number of pages, and only need to know if the next page exists, use Slice, since it does not do the "count" query:
for (int i = 0; ; i++) {
Slice<Organization> pageOrganization = organizationRepository.find(PageRequest.of(0, 100));
List<Organization> organizationList = pageOrganization.getContent();
for (Organization org : organizationList) {
// code
}
if (!pageOrganization.hasNext()) {
break;
}
}

Related

How to Add Pagination to a List Custom Query in JPA?

my repository looks like this:
public interface HeroRepository extends JpaRepository<Hero,Long>{
#Query(value = "SELECT h.heroname , SUM(h.killCount) AS killcount FROM Heroes AS h GROUP BY h.heroname ORDER BY h.heroname",nativeQuery = true)
List<IHero> findAllHeroByGroupName();
}
How do I add pagination to a custom query that doesnt use the default "findAll" queries by JPA?
How do I tell Spring to convert this to a Page or pageable object?
findAllHeroByGroupName()
so that in my AppController I can use it like this:
Page page = heroService.findAllHeroByGroupName(pageNum);
Take note, that findAllHeroByGroupName() returns a List and not a Page object.
You need to use Pageable
You method in repository class would look like:
public interface HeroRepository extends JpaRepository<Hero,Long>{
#Query(value = "SELECT h.heroname , SUM(h.killCount) AS killcount FROM Heroes AS h GROUP BY h.heroname ORDER BY h.heroname",nativeQuery = true)
List<IHero> findAllHeroByGroupName(Pageable pageable);
}
Now to fetch the records using Pagination, You can use something like:
Pageable firstPageWithTwoElements = PageRequest.of(0, 2);
The first argument is pagenumber and second argument is size. You can read more about PageRequest
List<IHero> allProducts = heroRepository.findAllHeroByGroupName(firstPageWithTwoElements);
The findAll(Pageable pageable) method by default returns a Page<T> object.
However, we can choose to return either a Page<T>, a Slice<T>, or a List<T> from any of our custom methods returning paginated data.
Read more about how to to use Native queries here

Spring Jpa Pageable get content using Java stream

I am doing a search to bring all registered cars 100 by 100 in a paginated way.
Pageable pageable = PageRequest.of(0, 100);
Page<Car> listOfcars = carService.findAll(pageable);
For me to get to the next page, I'm doing it via while:
while(listOfcars.hasNext()){
listOfcars = carService.findAll(listOfcars.nextPageable());
carService.start(listOfcars.getContent());
log.info("New batch sent" + listOfcars.getTotalElements());
}
There is a way to do this via the java stream, searching for the data on a page and right after that already searching for the sequences without having to do it via while ?
you can try by knowing total of available pages (maybe a total count will be needed first) and store each page numeric representation in a collection (let's say pages = [1, 2, ... n] ) then you can create a method OperateListOfCars and call your logic for each page with pages.stream()... maybe create a CustomPageResult wrapper and put there the pages collection will help to have the code more clean.
You don't need stream or loop here, you can use getContent method to return all content in a List from Page
Returns the page content as List.
Pageable pageable = PageRequest.of(0, 100);
Page<Car> listOfcars = carService.findAll(pageable);
List<Car> cars = listOfCars.getContent();

Spring Data Pagination returns wrong number of content as it is requested

currently I am developing an api which uses Spring Data Pagination and I came to the problem that I passing a Pageable object as a request to my repository with which page I want to receive and how many elements should be on it. And with that my object looks like: Pageable pageable = PageRequest.of(0, 2); - so I want first page with two elements. In my database are 3 objects so therefore there will be 2 pages. But what ide shows me is: screenshot. Can anyone tell me why it shows that content is an array of 3 elements but actually I asked for 2 elements?
#Override
public List<NotificationDto> getLast30NotificationsFor(ApplicationUser user) {
Pageable pageable = PageRequest.of(0, 2);
Page<Notification> first30ByOwnerIdOrderByCreatedAtDesc = notificationRepository.findFirst30ByOwnerIdOrderByCreatedAtDesc(user.getId(), pageable);
List<Notification> notifications = new ArrayList<>(first30ByOwnerIdOrderByCreatedAtDesc.getContent());
return notifications.stream()
.map(NotificationToDtoMapper::map)
.collect(toList());
}
Try:
#Override
public List<NotificationDto> getLast30NotificationsFor(ApplicationUser user) {
Pageable page = PageRequest.of(0,2, Sort.by("createdAt").descending());
return notificationRepository.findByOwnerId(user.getId(), page)
.getContent()
.stream()
.map(NotificationToDtoMapper::map)
.collect(toList());
}

SpringDataMongo MongoRepository pageable not sorted with geo-spatial method

I am facing a problem with sorting from Pageable with geo-spatial method in MongoRepository
With the following code I am able to retrieve first requestVo.per_page records when requestVo.page is 0. However the list is not sorted by title.
Another thing I have noticed is that the same PageRequest object is able to give me the sorted pageable list with photoRepository.findAll. Any help is appreciated!
LinkedList<Photo> photos= new LinkedList<Photo>();
PageRequest request = new PageRequest(requestVo.page, requestVo.per_page,Direction.ASC,"title");
for (GeoResult<Photo> photoResult : photoRepository.findByLocationNear(point, distance,request).getContent()) {
photos.add(photoResult.getContent());
}
return photos;
Turns out that GeoResult is blocking the sorting. Working perfect when I just return collection of Photo.
LinkedList<Photo> photos= new LinkedList<Photo>();
PageRequest request = new PageRequest(requestVo.page, requestVo.per_page,Direction.ASC,"title");
for (Photo photoResult : photoRepository.findByLocationNear(point, distance,request)) {
photos.add(photoResult);
}
return photos;

Spring Pageable PageRequest order by doesn't work

I use spring pageable for pagination.
#Transactional(readOnly = true)
#Override
public List<Node> getPageableList(int pageNumber, int pageSize) {
PageRequest pageRequest = new PageRequest(pageNumber, 15, Sort.Direction.DESC, "idNode");
return nodeRepository.getNodesByPage(pageRequest);
}
As you can see , I want to sort my list by "idNode". But still my list sorted by name. I use jquery datatable. Maybe it change in client side my sorting. How I can solve it ?
Thanks in advance.

Categories

Resources