Spring Boot Pagination

Pagination is importent when you handle the million of data. Java cannot loop the morethan 1lakh data, If you loop the 1lakh of data JVM throws the Stack Overflow Exception. To avoid such this kind of exception at runtime you can go with Pagination approach.

Pagination is an approach to split the records into multiple pages. each page should contains the minimum set of records. In java result set index is start with zero.

Page Class

Page is a Java POJO class, which has the records, startRecord, endRecord, pageNo, pageSize and noOfPage.

import java.util.List;

import lombok.Data;

public class Page<T> {
	private int startRec = 0;
	private int endRec = 0;
	private long recordCount = 0;
	private int noOfPage = 0;
	private int pageNo = 0;
	private int pageSize = 10;
	private List<T> records;
	public Page() {}
	public Page(int startRecord, long recordCount, int pageNo, int pageSize, List<T> records) {
		this.recordCount = recordCount;
		this.pageNo = pageNo;
		this.pageSize = pageSize;
		this.records = records;
	public void calcPage() {
		if(recordCount > 0) {
			noOfPage = (int) (recordCount / 10);
		endRec = startRec + (records != null ? records.size() : 0);


import java.util.ArrayList;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.util.StringUtils;

import com.samplecoder.entity.Profile;
import com.samplecoder.response.Page;

public class ProfileEntityRepository {
	private EntityManager entityManager;

	Predicate[] getPredicate(Root<Profile> root, CriteriaBuilder criteriaBuilder, Profile profile) {
		List<Predicate> li = new ArrayList<Predicate>();
		if (profile.getType() != null &&  StringUtils.hasText(profile.getType())) {
			li.add(criteriaBuilder.equal(root.get("type"), profile.getType()));

		return li.toArray(new Predicate[li.size()]);

	public Page<Profile> list(Profile profile, int pageNo, int pageSize) {

		int startRecord = pageNo * pageSize;

		CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
		CriteriaQuery<Profile> criteriaQuery = criteriaBuilder.createQuery(Profile.class);
		Root<Profile> from = criteriaQuery.from(Profile.class);

		CriteriaQuery<Profile> select = criteriaQuery.select(from);
		Predicate[] predicates = getPredicate(from, criteriaBuilder, profile);

		TypedQuery<Profile> typedQuery = entityManager.createQuery(select);
		List<Profile> records = typedQuery.getResultList();

		CriteriaQuery<Long> countQuery = criteriaBuilder.createQuery(Long.class);
		Predicate[] predicates1 = getPredicate(from, criteriaBuilder, profile);
		Long recordCount = entityManager.createQuery(countQuery).getSingleResult();

		return new Page<Profile>(startRecord, recordCount, pageNo, pageSize, records);


	private Page<Profile> list(@NotNull @RequestBody Profile profile, @PathVariable("pageNo") int pageNo, @PathVariable("pageSize") int pageSize){
		return profileService.list(profile, pageNo, pageSize);