How to setup Pagination in Spring Boot and Hibernate
Implement pagination in APIs
When dealing with large amounts of data in a front-end application, we often need to break it down to smaller chucks so as to not overwhelm the user. Hence in front-end application we display large chucks of data as pages. Using this technique, we can request only required data for displaying only a single page at a time. To achieve this, we require pagination in API requests
Spring boot makes it easy to setup pagination with hibernate.
1. First we need to create the entity,
Entity
@Table(name = "test_details")
public class TestDetails {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "test_id")
@SequenceGenerator(name = "test_id", sequenceName = "test_id", allocationSize = 1)
@Column(name = "test_id")
private Integer testId;
@Column(name = "test_name")
private String testName;
public TestDetails() {
}
public Integer getTestId() {
return testId;
}
public void setTestId(Integer testId) {
this.testId = testId;
}
public String getTestName() {
return testName;
}
public void setTestName(String testName) {
this.testName = testName;
}
}
2. Then create the repository. Here it should extend PagingAndSortingRepository
@Repository
public interface TestRepository extends PagingAndSortingRepository<TestDetails,Integer>{
@Query(value="SELECT u FROM TestDetails u order by u.testId ASC")
List<TestDetails> getAllTests(Pageable pageable);
}
3. Now create a PageRequest
object and pass it to the above repository method
PageRequest.of(pageNum-1, pageSize)
Here PageRequest
starts from zeroth index, hence if user passes pageNum
parameter as 1, to get the first set of data, we subtract it by 1.
4. Finally write the implementation method as follows,
@Override
public List<TestDetails> getTests(Integer pageNum, Integer pageSize) throws TestNotFoundExpection {
List<TestDetails> testDetailsList = testRepository.getAllTests(PageRequest.of(pageNum-1, pageSize));
if(testDetailsList.size()>0) {
return testDetailsList;
}
}else {
throw new TestNotFoundExpection("No Test in page number "+pageNum);
}
}
Common error observed:
If there are any entities with 1:M relation within TestDetails
entity we might get below error,
[org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: TestDetails.items
To resolve this error, declare implementation method as @Transactional
@Transactional
@Override
public List<TestDetails> getTests(Integer pageNum, Integer pageSize) throws TestNotFoundExpection {
List<TestDetails> testDetailsList = testRepository.getAllTests(PageRequest.of(pageNum-1, pageSize));
if(testDetailsList.size()>0) {
return testDetailsList;
}
}else {
throw new TestNotFoundExpection("No Test in page number "+pageNum);
}
}
Hope this article provides a primer on implementing API pagination using Spring boot
Checkout more Java related articles here