Pagination and Sorting using Spring Data JPA

This article deeps dive into exposing REST API that supports pagination using Spring DATA JPA.


Pagination is a way to get a subset(page) of data on a fixed page and be able to retrieve the pages randomly or sequentially. Most important parameters are,

Total number of records
Number of records on a page (page size)
Current Page number (page order number) Based on the above informations we can build the algorithm to fetch the respective data. In the SQL world given the current page and page size, we can retrieve the information using limit and offset like follows, Select * from [TABLE NAME] limit pageSize, offset pageNumber*pageSize Spring Data encapsulates all these algorithms/queries and handles all edge cases to return us paginated data.
In the next section we will walk through a sample REST API Controller which uses Spring Data JPA to return paginated response.

Model class representing Dish object which holds information of about dishes.
@Table (name = "dish_table")
public class Dish {

	@Column(name = "id")
	private Long id;
	@Size(min=2, message="Name should have atleast 5 characters")
	@Column(name = "name")
	private String name;
	@Column(name = "description")
	private String description;
	@Column(name = "lowprice")
	private Double lowPrice;
	@Column(name = "highprice")
	private Double highPrice;
	public Dish () {}
	//Getter and Setters
Dish Repository extends JpaRepository which extends interface PagingAndSortingRepository that provides methods like Page findAll(Pageable pageable);. On top of that, we have specified our own method which returns a paginated response and takes a name as the first parameter and Pageable as the second parameter.
public interface DishRepository extends JpaRepository {
	public Page findByName(String name, Pageable pageable);
Our Rest controller uses repository method findAll(pageRequest). We need to build the pageRequest object and pass it to the repository method. We are getting the pageNo as request parameter.
public class DishControllerPaginatedV2 {

	private static final int  pageSize = 2;

	DishRepository repo;
	@GetMapping(value="/dishes",produces = MediaType.APPLICATION_JSON_VALUE)
	public ResponseEntity> getDish3(@RequestParam (defaultValue = "0") int pageNo) throws Exception {
		Sort sort ="name");
		Pageable pageReq =  PageRequest.of(pageNo, pageSize, sort);
		Page result =  repo.findAll(pageReq);
		return ResponseEntity.ok(result);
invoking the API with the following curl will provide us paginated response as shown in the next block.
curl --request GET \
  --url 'http://localhost:8080/api/v1/dishes3?pageNo=0' \
  --header 'cache-control: no-cache'
    "content": [
            "id": 12,
            "name": "Anchovies",
            "description": "Anchovies",
            "lowPrice": 1987,
            "highPrice": 0
            "id": 14,
            "name": "Celery",
            "description": "Celery",
            "lowPrice": 2928,
            "highPrice": 0
    "pageable": {
        "sort": {
            "sorted": true,
            "unsorted": false,
            "empty": false
        "offset": 0,
        "pageNumber": 0,
        "pageSize": 2,
        "paged": true,
        "unpaged": false
    "last": false,
    "totalPages": 7,
    "totalElements": 14,
    "size": 2,
    "number": 0,
    "sort": {
        "sorted": true,
        "unsorted": false,
        "empty": false
    "numberOfElements": 2,
    "first": true,
    "empty": false


In this article, we saw how to quickly build paginated REST API using Spring Data JPA. We need to create the PageRequest object and call the repository method findALL(pageRequest). Spring Data will take care of the offset calculation and will return one page of data along with some important information. Spring Data also supports filtering and sorting along with pagination.