Make RepositoryItemWriter use CrudRepository#saveAll by default

See original GitHub issue

As of v4.2.2, the javadocs of RepositoryItemWriter state that the performance of the writer is determined by the performance of CrudRepository#saveAll. However, the implementation does not call CrudRepository#saveAll, but uses a for loop in which the selected method is performed for each item.

This means that even if I want to use the saveAll method by setting setMethodName("saveAll"), the saveAll method will be called for each item and not only once for all items. To use the saveAll method, one needs to extend the writer and override doWrite which is not convenient. Moreover, there is no validation that a method name is provided currently.

I understand that the motivation behind this “methodName” parameter is to allows users to select any method that might take a single item as a parameter and not a list (like update(item) or save(item), etc), but I think it would be better to default to using saveAll. In fact, the whole intent of the ItemWriter concept in the first place is bulk updates, by making it operate on a list of items by design.

Using saveAll instead of save is 2x faster according to my first benchmark. I believe the cost of creating a MethodInvoker and calling the method via reflection + not using a bulk operation is the root of this performance penalty.

My suggestion here is to use saveAll by default (this will be consistent with Javadoc, which is not the case at the moment) and use the current behaviour if a method name is provided. Note that the RepositoryItemWriterBuilder enforces that a method name is provided (which is a good point but not consistent with the writer that does not perform any validation), but this constraint can be relaxed to make things consistent and to benefit from the performance boost by default.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:6 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
cfbocommented, Jul 10, 2020

@benas Thanks for your reply. That makes sense.

1reaction
fmbenhassinecommented, Jun 3, 2020

@parikshitdutta I have already started working on this (see fc9de63), that’s why I assigned it to myself. To avoid duplicate efforts, you can take something else from the 4.3 milestone. No need to ask, you can take anything that is unassigned and has no PR associated with it. Thank you upfront!

Read more comments on GitHub >

github_iconTop Results From Across the Web

Performance Difference Between save() and saveAll() in ...
In order to test the performance, we'll need a Spring application with an entity and a repository. Let's create a book entity:
Read more >
RepositoryItemWriter (Spring Batch 5.0.0 API)
By default, this writer will use CrudRepository.saveAll(Iterable) to save items, unless another method is selected with setMethodName(java.lang.String) .
Read more >
spring boot - Entities not persisting. Are RepositoryItemWriter ...
Looks like I fixed it by adding a PlatformTransactionManager. ... distillerDataSource() { return DataSourceBuilder.create().build(); } @Bean ...
Read more >
Spring Data CrudRepository saveAll() and findAll() - - JavaTute
In this article, we will see about Spring Data CrudRepository saveAll() and findAll() Methods Example using Spring Boot and Oracle.
Read more >
The differences between Spring Data JPA's save ...
Spring Data JPA's save, saveAll and saveAndFlush methods seem to do the same, ... But to make the article a little easier to...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found