3

I have a method called getAllEmployees() which returns a pageable.

Lets say the page size is 1 and started with page 0

Pageable pageable = PageRequest.of(0, 1);

 Page<String> allEmployees = service.getAllEmployeeNames(pageable)
 while(true) {

       for(String name: allEmployees.getContent()) {

          // check whether the employee needs to be deleted or not based on certain conditions
          boolean isDelete = service.checkEmployeeToBeDeleted() 

          if (isDelete)
            EmployeeEntity entity = service.findByName(name);
            service.delete(entity);

        }

       if (!page.hasNext()) {
            break;
        }

        pageable = page.nextPageable();
 }
  • In this scenario, all employees are not deleted only those matching the condition will be deleted

as page size is 1

Let's say, total 6 employees

 emp      pageable(pageNumber, pageSize)

 1        (0 ,1) 
 2        (1 ,1) 
 3        (2 ,1) 
 4        (3 ,1) 
 5        (4 ,1) 
 6        (5 ,1) 

when 1 gets deleted the pageable will be like

2    (0 ,1) 
3    (1 ,1) 
4    (2 ,1) 
5    (3 ,1) 
6    (4 ,1) 

but as we go with page.nextPageable() the next one will be like (1,1)

So on next fetch, it will pick emp 3, and emp 2 will be missed

Cork Kochi
  • 1,783
  • 6
  • 29
  • 45

2 Answers2

4

I had a similiar problem. The problem is that you are doing the 'search' and the 'deletion' in one step while you are on an iteration. So the deleting will modify the search, but you are one step further with you initial search. (I think this is the main problem).

My solutin was, first search ALL objects that need to be deleted and put them into a list. And after the searching, delete those objects. So your code could be something like:

Page<String> allEmployees = service.getAllEmployeeNames(pageable)

List<EmployeeEntity> deleteList = new ArrayList<>();
while(true) {

   for(String name: allEmployees.getContent()) {

      // check whether the employee needs to be deleted or not based on certain conditions
      boolean isDelete = service.checkEmployeeToBeDeleted() 

      if (isDelete)
        EmployeeEntity entity = service.findByName(name);
        deleteList.add(entity);
    }

   if (!page.hasNext()) {
        // here iterate over delete list and service.delete(entity);
        break;
    }

    pageable = page.nextPageable();
 }
Mafick
  • 1,128
  • 1
  • 12
  • 27
  • Thanks. We had a similar issue, only in our case our object can be big, so we're using id to mark `List deleteList`, and later `repository.deleteById(uuid)`. – John Smith Oct 15 '20 at 20:20
  • Also a good idea. But in Java as far as I know we also work mainly with 'references' and not the objects in the memory. So I dont know if it is important to work with marks. – Mafick Oct 19 '20 at 07:26
0

You need only use nextPageable() when you not delete employee. Just add conditions like this:

if (!isDelete) { 
    pageable = page.nextPageable();
}
Do Trung Duc
  • 396
  • 3
  • 13