Close

Spring Data JPA - Web Support, resolving Pageable instance from request parameters for pagination

[Last Updated: Jun 12, 2018]

The web support configuration we saw in the last tutorial also registers PageableHandlerMethodArgumentResolver which resolves pagination related query parameters (e.g. page=0&size=10) to Pageable used as a controller method argument. This would be equivalent to if Pageable instance was create as PageRequest.of(0, 10) (check out related tutorial).

Example

JPA entity

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

Repository

public interface EmployeeRepository extends PagingAndSortingRepository<Employee, Long> {
}

MVC Controller

For simplicity we are going to create HTML content in the controller method instead of using a proper view in this example.

@RestController
public class EmployeeController {
  private static final String LinkFormat =
          "<a href='http://localhost:8080/employees?page=%s&size=%s'>%s</a><br/>";
  @Autowired
  private EmployeeRepository repository;

  @GetMapping("/employees")
  public String getEmployees(Pageable pageable) {
      Page<Employee> page = repository.findAll(pageable);
      List<Employee> employees = page.getContent();
      String response = employees.stream()
                                 .map(Employee::toString)
                                 .collect(Collectors.joining("<br/>"));
      response += "<br/><br/>";
      if (page.hasPrevious()) {
          response += String.format(LinkFormat, page.getNumber() - 1, page.getSize(),
                  "Previous Page");
      }
      if (page.hasNext()) {
          response += String.format(LinkFormat, page.getNumber() + 1, page.getSize(),
                  "Next Page");
      }
      return response;
  }
}

Populating test data

@Component
public class DataInitializer {
  @Autowired
  private EmployeeRepository repository;

  @PostConstruct
  void postConstruct() {
      repository.saveAll(createEmployees());
  }

  private List<Employee> createEmployees() {
      String[] departments = {"IT", "Sales", "Admin", "Account"};
      List<Employee> employees = new ArrayList<>();
      for (int i = 0; i < 100; i++) {
          employees.add(Employee.create(RandomUtil.getName(),
                  RandomUtil.getAnyOf(departments),
                  RandomUtil.getInt(1, 10) * 1000));
      }
      return employees;
  }
}

The JavaConfig class is same as the last example one.

Running

To try examples, run embedded tomcat (configured in pom.xml of example project below):

mvn tomcat7:run-war

Output

http://localhost:8080/employees?page=0&size=10

clicking on 'Next Page' link:

Default parameters and using @PageableDefault

If we don't supply any pagination query parameters i.e. make request with just localhost:8080/employees then defaults will be used with page number 0 and page size 20. We can change this defaults by using @PageableDefault, for example:

  @GetMapping("/employees")
  public String getEmployees(@PageableDefault(page=0, size=10) Pageable pageable) {
  .....
  }

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
  • spring-webmvc 5.0.6.RELEASE: Spring Web MVC.
  • jackson-databind 2.9.5: General data-binding functionality for Jackson: works on core streaming API.
  • javax.servlet-api 3.0.1 Java Servlet API
  • 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

Web support for pagination Select All Download
  • spring-data-jpa-pageable-method-arg-resolver
    • src
      • main
        • java
          • com
            • logicbig
              • example
                • EmployeeController.java
          • resources
            • META-INF

    See Also