2

I have to write some REST service which should handle a million entries and return a response to the user in JSON format. I'm writing some REST-controller using Spring and make pagination.

public List<ContactDto> getAllContacts() { double countItems = contactRepo.count(); int pages = (int) Math.ceil(countItems / totalItemsPerPage); List<Contact> contacts = new ArrayList<>(); for (int i = 0; i < pages; i++) { Page<Contact> page = contactRepo.findAll(PageRequest.of(i, totalItemsPerPage)); contacts.addAll(page.stream().collect(Collectors.toList())); } return contacts.stream() .map(entity -> new ContactDto(entity.getId(), entity.getName())) .collect(Collectors.toList()); } 

I'm new in spring and pagination.

In this approach is have a sense or I'm doing something wrong?

I mean I want to know I'm using pagination write or wrong?

Thanks for the help!

3
  • If you're at any time keeping a million entries in memory, then this won't scale. Seems to me above keep reads all entries in memory, and just splits them into pages (but it's all still in memory). When dealing which such large numbers, it's best to do a specific query to the database that only returns the page needed (or perhaps a couple of pages and cache those for a while in case the client wants those next). Commented May 26, 2019 at 8:22
  • @john16384 I have a task and I have to get all data from a database and process it in a Java code. And I don't know what is the best way to get the best performance? I should get all data from the database using pagination or without it? After reading all data from database I keep it in a cache. Commented May 26, 2019 at 8:38
  • If you do not need to process all entites together, you could use the reactive stack from Spring to return a stream of data; get the data in pages from the database, process it and then send it to the client before getting the next page and so on Commented May 26, 2019 at 9:12

2 Answers 2

1

It seems that you are collecting all the Contacts from all the pages and that does not make sense as you are storing all the data in memory negating all the lazy loading benefints.

I would suggest the following:

1.Rest controller should be able to accept pageNumber and pageSize arguments:

@GetMapping(value="/uri/{pageNumber}/{pageSize}") public List<Contact> getContactsPage(@PathVariable("pageNumber") final Integer pageNumber, @PathVariable("pageSize") final Integer pageSize) { //service or repository call } 

2.Repository interface should extent PagingAndSortingRepository:

public interface ContactRepository extends PagingAndSortingRepository<Contact, Long> { Page<Contact> fingAll(Pageable pageable); } 

3.In your service or in controller directly create a Pageable object and pass it as ContactRepository#fingAll() argument:

final Pageable contactsPageable = PageRequest.of(pageNumber, pageSize); 

4.Map Page to DTO if necessary.

Sign up to request clarification or add additional context in comments.

Comments

0

You should take a look at Spring Data Rest.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.