Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How many times Database is hit in Spring DATA JPA's save(Iterable<S> entities)

I have the following lines of code:

@RequestMapping(value="/persons",method = RequestMethod.POST)
@ResponseBody
public ResponseEntity<List<Person>> saveUsers(@RequestBody List<Person> persons) {
        persons = (List<Person>) userRepository.save(persons);
        return new ResponseEntity<List<Person>>(persons, HttpStatus.OK);
}

And here is the repository:

@Transactional
public interface UserRepository  extends UserBaseRepository<User> { 
}

@NoRepositoryBean
public interface UserBaseRepository<T extends User> extends CrudRepository<T, Long> {
    public T findByEmail(String email);
}

It runs fine. While running the code I see the following logs.

Hibernate: insert into user (email, firstname, lastname, user_type) values (?, ?, ?, 'Person')
Hibernate: insert into user (email, firstname, lastname, user_type) values (?, ?, ?, 'Person')
Hibernate: insert into user (email, firstname, lastname, user_type) values (?, ?, ?, 'Person')
Hibernate: insert into user (email, firstname, lastname, user_type) values (?, ?, ?, 'Person')

It seems that, the DataBase is hit 4 times. I have seen the implementation of save(iterable e) method, where the for loop is run to save each entity. So, my questions is:

  1. is the DB hit 4 times ?
  2. if so, then can it be done in 1 db hit (using Spring Data JPA) ? By doing so, will it give a performance boost in case of inserting a large number of records ?
like image 294
Avik Dutta Avatar asked Aug 29 '17 16:08

Avik Dutta


People also ask

Is saveAll faster than save?

saveAll(bookList); In our tests, we noticed that the first method took around 2 seconds, and the second one took approximately 0.3 seconds. Furthermore, when we enabled JPA Batch Inserts, we observed a decrease of up to 10% in the performance of the save() method, and an increase of up to 60% on the saveAll() method.


2 Answers

Yes, you are querying the data four times.

You can have the insertion done in one batch statement by implementing Hibernate Batching. In particular, take a look at performing batch inserts. Using batch inserts, you must control the session manually by making explicit calls to the flush() and clear() methods in the session.

Also, consider setting the appropriate Hibernate Batching Properties such as the batch size (default 5), and if applicable, permission for Hibernate to re-order insertions and updates before constructing the batch statements:

hibernate.jdbc.batch_size = 25
hibernate.order_inserts = true
hibernate.order_updates = true
like image 105
David Yee Avatar answered Oct 31 '22 20:10

David Yee


From the docs on Hibernate Batching:

Hibernate disables insert batching at the JDBC level transparently if you use an identity identifier generator.

So, if Person is using an Identity generator (as opposed to the Sequence generator or TABLE generator) batching won't take place. See this section for more details on why that is so.

like image 32
jacaetevha Avatar answered Oct 31 '22 21:10

jacaetevha