Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why Spring Data JPA's save() is slow when called on a single record vs calling it on a list of records?

Tags:

I'm experiencing a major time reduction when using save function from SimpleJpaRepository on a single record vs calling save on a list of records.

The loop below takes 10 times longer than the list.

    for (Record r : csvRecords) {
            myRepository.save(r);
    }

myRepository doesn't have any @Transactional annotations at all. But the loop below is blazingly fast in comparison to the above.

List<Record> myArray = new ArrayList();
for (Record r : csvRecords) {
        myArray.add(r);
}
myRepository.save(myArray);

if we look at the save implementation from SimpleJpaRepository

@Transactional
public <S extends T> List<S> save(Iterable<S> entities) {

   List<S> result = new ArrayList<S>();

   if (entities == null) {
      return result;
   }

   for (S entity : entities) {
      result.add(save(entity));
   }

   return result;
}

This implementation just masks the single save operation so it shouldn't make any difference if I first store my data in a buffer or I call save on each of my record therefore the speed increase doesn't make any sense for me .

EDIT: using the docs.spring.io/autorepo/docs/spring-data-commons/1.5.1.RELEA‌​SE/ version .

like image 423
Oleg Avatar asked Nov 24 '17 10:11

Oleg


1 Answers

In the case of a single entry you are opening 10 transactions - that need to be opened and closed; in the case of the List the save(singleEntry) (that is used inside saveAll) will re-use the already opened transaction, so it's a single one that is opened and closed. And btw if I re-call correctly its saveAll(Iterable) not save(Iterable).

like image 173
Eugene Avatar answered Sep 23 '22 13:09

Eugene