I loop over person entities of a jpa streamresult and call for every single person an update service bean to update the name of the person entity. I understand, that envers is executed at the end of the transaction. Ok this works fine and all entities are updated and have an AUD table entry, but with a single revision for all.
How I tell spring to do a for every person entity a single transaction , so that envers writes for every updated entity a single update revision instead for all updated person entities? I tried also to put @Transactional(propagation = Propagation.REQUIRES_NEW)
to the top of the update service class, but envers isn't triggered for every item. It seems that all updates are executed in one transaction, but I need a single transacion for every call of the update service bean.
The stream service:
@Service
class StreamService {
@Autowired
PersonRepository repo;
@Autowired
FooService fooService;
@Transactional
public void uppercaseAllNames() {
Stream<Person> stream = repo.findAllPersons();
// change name for each person
stream.forEach(fooService::doFoo);
}
}
The simplified update service:
@Service
@Transactional(propagation = Propagation.REQUIRES_NEW) // <=== create new transaction
class FooService {
@Autowired
PersonRepository repo;
doFoo(Person person) {
String name = person.getName();
person.setName(name.toUpperCase());
repo.save(person); // <=== save trigger envers
}
}
Solution:
The save operation trigger envers to create a revision per person entity, but this solution works in our project only with @Transactional(propagation = Propagation.REQUIRES_NEW)
. A single @Transactional
doesn't work. The annotation can be placed at method or class level, booth places work.
Remove the
@Transactional
fromuppercaseAllNames
. This will give you a separate transactions for the read and each write.You'll need to add a
personRepo.save(person)
to theFooService.doFoo
in order to persist the changes.It might be that the second change is sufficient with
Propagation.REQUIRES_NEW
, but I find nested transactions rather confusing and would recommend to avoid them.