Close

Spring Data JPA - Pagination using Pageable parameter and returning Page

[Updated: May 31, 2018, Created: May 31, 2018]

For pagination process, Spring Data also supports Page as a return type of the query method. Pageable parameter must be specified by the same query method.

As opposed to Slice (last tutorial), Page knows about the total number of elements and pages available. It does so by triggering a count query to calculate the overall number. This might be expensive for large number of dataset.

Page is a subclass of Slice.

Example

Entity

@Entity
public class Employee {
  private @Id
  @GeneratedValue
  Long id;
  private String name;
  private String dept;
  private int salary;
    .............
}

Repository

package com.logicbig.example;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.repository.CrudRepository;

public interface EmployeeRepository extends CrudRepository<Employee, Long> {

  public Page<Employee> findByDept(String deptName, Pageable pageable);
}

Example Client

@Component
public class ExampleClient {

  @Autowired
  private EmployeeRepository repo;

  public void run() {
      List<Employee> employees = createEmployees();
      repo.saveAll(employees);

      System.out.println(" -- finding all employees --");
      Iterable<Employee> all = repo.findAll();
      all.forEach(System.out::println);
      System.out.println(" -- paginating where dept is Sales --");
      Page<Employee> page = null;
      Pageable pageable = PageRequest.of(0, 3, Sort.by("salary"));
      while (true) {
          page = repo.findByDept("Sales", pageable);
          int number = page.getNumber();
          int numberOfElements = page.getNumberOfElements();
          int size = page.getSize();
          long totalElements = page.getTotalElements();
          int totalPages = page.getTotalPages();
          System.out.printf("page info - page number %s, numberOfElements: %s, size: %s, "
                          + "totalElements: %s, totalPages: %s%n",
                  number, numberOfElements, size, totalElements, totalPages);
          List<Employee> employeeList = page.getContent();
          employeeList.forEach(System.out::println);
          if (!page.hasNext()) {
              break;
          }
          pageable = page.nextPageable();
      }
  }

  private List<Employee> createEmployees() {
      return Arrays.asList(
              Employee.create("Diana", "Sales", 2000),
              Employee.create("Mike", "Sales", 1000),
              Employee.create("Rose", "IT", 4000),
              Employee.create("Sara", "Sales", 3000),
              Employee.create("Andy", "Sales", 3000),
              Employee.create("Charlie", "Sales", 2500),
              Employee.create("Jim", "Sales", 4500),
              Employee.create("Sam", "Sales", 2500),
              Employee.create("Adam", "Sales", 5000),
              Employee.create("Jane", "Sales", 5500),
              Employee.create("Joe", "Sales", 1500)
      );
  }
}

Main class

public class ExampleMain {

  public static void main(String[] args) {
      AnnotationConfigApplicationContext context =
              new AnnotationConfigApplicationContext(AppConfig.class);
      ExampleClient exampleClient = context.getBean(ExampleClient.class);
      exampleClient.run();
      EntityManagerFactory emf = context.getBean(EntityManagerFactory.class);
      emf.close();
  }
}
 -- finding all employees --
Employee{id=1, name='Diana', dept='Sales', salary=2000}
Employee{id=2, name='Mike', dept='Sales', salary=1000}
Employee{id=3, name='Rose', dept='IT', salary=4000}
Employee{id=4, name='Sara', dept='Sales', salary=3000}
Employee{id=5, name='Andy', dept='Sales', salary=3000}
Employee{id=6, name='Charlie', dept='Sales', salary=2500}
Employee{id=7, name='Jim', dept='Sales', salary=4500}
Employee{id=8, name='Sam', dept='Sales', salary=2500}
Employee{id=9, name='Adam', dept='Sales', salary=5000}
Employee{id=10, name='Jane', dept='Sales', salary=5500}
Employee{id=11, name='Joe', dept='Sales', salary=1500}
-- paginating where dept is Sales --
page info - page number 0, numberOfElements: 3, size: 3, totalElements: 10, totalPages: 4
Employee{id=2, name='Mike', dept='Sales', salary=1000}
Employee{id=11, name='Joe', dept='Sales', salary=1500}
Employee{id=1, name='Diana', dept='Sales', salary=2000}
page info - page number 1, numberOfElements: 3, size: 3, totalElements: 10, totalPages: 4
Employee{id=8, name='Sam', dept='Sales', salary=2500}
Employee{id=6, name='Charlie', dept='Sales', salary=2500}
Employee{id=4, name='Sara', dept='Sales', salary=3000}
page info - page number 2, numberOfElements: 3, size: 3, totalElements: 10, totalPages: 4
Employee{id=4, name='Sara', dept='Sales', salary=3000}
Employee{id=7, name='Jim', dept='Sales', salary=4500}
Employee{id=9, name='Adam', dept='Sales', salary=5000}
page info - page number 3, numberOfElements: 1, size: 3, totalElements: 10, totalPages: 4
Employee{id=10, name='Jane', dept='Sales', salary=5500}

Example Project

Dependencies and Technologies Used:

  • spring-data-jpa 2.0.7.RELEASE: Spring Data module for JPA repositories.
    Uses org.springframework:spring-context version 5.0.6.RELEASE
  • hibernate-core 5.3.1.Final: Hibernate's core ORM functionality.
    Implements javax.persistence:javax.persistence-api version 2.2
  • h2 1.4.197: H2 Database Engine.
  • JDK 1.8
  • Maven 3.3.9

Spring Data JPA - Pageable with Page Example Select All Download
  • spring-data-jpa-returning-page
    • src
      • main
        • java
          • com
            • logicbig
              • example
                • EmployeeRepository.java
          • resources
            • META-INF

    See Also