Sum_Pie
Sum_Pie

Reputation: 185

JPA: Why save and saveAll are working async?

I'm using JPA save and saveAll to save entities on my application. But I've 2 different behaviour:

first case: in a method that return the list of saved entities

List<Entity> savedEntities = entityRepo.saveAll(listEntitiesToSave);
voidMethod(savedEntities);
return savedEntities;

In this first case entities are stored immediately. This is the behaviour that I expected.

second case: in a void method, as last line

entityRepo.saveAll(listEntitiesToSave);

In this second case entities are not stored immediately: I think that could be possible only because in the first case the saved entities are used. How is it possible? Do I need add flush()? But also in this case it's strange. I don't have async active.

Upvotes: 1

Views: 4088

Answers (1)

Sum_Pie
Sum_Pie

Reputation: 185

I found my mistake: the parent method that call my saving methods had @Transactional on top. Transactional call flush method only when the method is finished. This was my case:

@Transactional
private void parentMethod(){

  service.mySavingMethod1();
  service.mySavingMethod2();
  anotherService.sendEmail();
}

So the user received the email before mySavingMethods had finished. I tried 2 solutions:

  • Fast way: adding, where needed, flush after save/saveAll
  • Elegant way: remove @Transactional on parent method, create another service, put the list of savingMethods and add the annotation @Transactional. So we'll have:

    private void parentMethod(){
     newMiddleService.mySavingMethods();
     anotherService.sendEmail();}
    

    @Service public class NewMiddleService(){ @Transactional public void mySavingMethods(){ service.mySavingMethod1(); service.mySavingMethod2(); } }

If you need transactional also in the parent method, could be better call on NewMiddleService, Transactional(propagation = Requires.NEW)

Upvotes: 3

Related Questions