Close

Spring Data JPA - Pagination using Pageable parameter and returning Slice

[Last Updated: May 31, 2018]

In the last tutorial we saw how do pagination using Pageable parameter in query methods. In this tutorial we will see how Slice can help us in pagination process.

Slice is a sized chunk of data with an indication of whether there is more data available.

Spring supports Slice as a return type of the query method. Pageable parameter must be specified by the same query method.

Slice avoids triggering a count query to calculate the overall number of pages as that might be expensive. A Slice only knows about whether a next or previous Slice is available, which might be sufficient when walking through a larger result set.

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.domain.Slice;
import org.springframework.data.repository.CrudRepository;

public interface EmployeeRepository extends CrudRepository<Employee, Long> {

  public Slice<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 --");
      Slice<Employee> slice = null;
      Pageable pageable = PageRequest.of(0, 3, Sort.by("salary"));
      while (true) {
          slice = repo.findByDept("Sales", pageable);
          int number = slice.getNumber();
          int numberOfElements = slice.getNumberOfElements();
          int size = slice.getSize();
          System.out.printf("slice info - page number %s, numberOfElements: %s, size: %s%n",
                  number, numberOfElements, size);
          List<Employee> employeeList = slice.getContent();
          employeeList.forEach(System.out::println);
          if (!slice.hasNext()) {
              break;
          }
          pageable = slice.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 --
slice info - page number 0, numberOfElements: 3, size: 3
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}
slice info - page number 1, numberOfElements: 3, size: 3
Employee{id=6, name='Charlie', dept='Sales', salary=2500}
Employee{id=8, name='Sam', dept='Sales', salary=2500}
Employee{id=4, name='Sara', dept='Sales', salary=3000}
slice info - page number 2, numberOfElements: 3, size: 3
Employee{id=5, name='Andy', dept='Sales', salary=3000}
Employee{id=7, name='Jim', dept='Sales', salary=4500}
Employee{id=9, name='Adam', dept='Sales', salary=5000}
slice info - page number 3, numberOfElements: 1, size: 3
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 - Pagination with Slice Example Select All Download
  • spring-data-jpa-returning-slice
    • src
      • main
        • java
          • com
            • logicbig
              • example
                • EmployeeRepository.java
          • resources
            • META-INF

    See Also