Spring data mongo pagination

Viewed 36522

I want to implement pagination with Spring Data Mongo. There are many tutorials and docs suggest to use PagingAndSortingRepository, like this:

StoryRepo extends PagingAndSortingRepository<Story, String>{}

And so because PagingAndSortingRepository provides api for query with paging, I can use it like:

Page<Story> story = storyRepo.findAll(pageable);

My question is where actually is this findAll method here implemented? Do I need to write its implementation by myself? The StoryRepoImpl which implements StoryRepo needs to implement this method?

7 Answers

I got it working by writing my own implementations, something like this:

List<Story> stories = null;

Query query = new Query();
query.with(pageable);

stories = getTemplate().find(query, Story.class);

long total = getTemplate().count(query, Story.class);
Page<Story> storyPage = new PageImpl<Story>(stories, pageable, total);

return storyPage;

I'm working with spring data & mongodb, using mongo template to query data.

In Spring Data, you create an interface and add a method using the naming conventions used by Spring data and the framework will generate the implementation of that method. To implement pagination, i create this method declaration in my repository:

public interface PersonRepository extends MongoRepository<Person, ObjectId> {
    Page<Person> findByName(String name, Pageable pageable);
}

Then, in my service i call this method like this:

Page<Person> persons = personRepository.findByName("Alex", PageRequest.of(0, 100));

Here, the page will contain 100 element.

The method is implemented by a store-specific class. For the Spring Data JPA module, it's SimpleJpaRepository. You usually let a DI container create instances for these repository interfaces. With Spring you'd activate Spring Data repositories by either using @EnableJpaRepository on a JavaConfig class or

<jpa:repositories base-package="com.acme.repositories" />

This will create a proxy instance for the repo, so that you can get it injected into your clients:

class MyClient {

  @Inject
  public MyClient(PersonRepository repository) {
    …
  }
}
Query query1 = new Query();
Integer startIndex = page * size;
Integer endIndex = (page * size) + size;

List<dto> totalRecord = mongoOperation.find(query1, dto.class);

query1.limit((endIndex > totalRecord.size() ? totalRecord.size() : endIndex));

List<dto> responseList = mongoOperation.find(query1, dto.class);

int end = (endIndex > (totalRecord.size() - 1) ? totalRecord.size() - 1 : endIndex);
if (totalRecord.size() > 0 && end == 0)
  end = 1;

if (totalRecord.size() > 0)
  responseList = responseList.subList(startIndex, end);

int totalPages = totalRecord.size() / size + (totalRecord.size() % size == 0 ? 0 : 1);

As other answer says: you don't need to implement the repository interface classes. The generating magic will handle it.

I wrote this answer because of say implementation way of PageRequest deprecated -the Pageable pageable = new PageRequest(fromIndex, toIndex); one.

If you want to implement a pageable request nowadays, you need to use like following:

PageRequest page = PageRequest.of(pageNum, pageSize);

List<MyEntity> result =myEntityRepository.findAll(page).toList();


Related