I am sure that I am missing something, but I don't know exactly what...
Giving the following snippet:
@Service
public class MyClass {
private MyClass self;
private UserRepository userRepository;
private ApplicationContext applicationContext;
@PostConstruct
private void init() {
self = applicationContext.getBean(MyClass.class);
}
@Transactional
public void doA(User user) {
...
if (condition) {
self.doB(user);
throw new SecurityException();
}
user.setRandomField("x");
userRepository.save(user);
}
@Transactional(value = Transactional.TxType.REQUIRES_NEW)
public void doB(User user) {
...
userRepository.save(user);
}
}
What do I know about @Transactional
is that if it is used, is redundant to call repository.save(entity)
.
What I am trying to do, is to process an entity from a transactional method, and if there is a breaking condition, call a new method (annotated with REQUIRES_NEW
) that will update some fields of the entity and save it. The root method (doA
) then throws an exception. FYI: the @Transactional(dontRollbackOn = SecurityException.class)
is not an option in this situation.
For using this commiting mechanism, instead of creating a new bean just with one method I just injected the current bean into a variable just called self
, therefore I can use the bean proxy for transaction management.
The odd thing is that if I am removing from doB
the save
call, when doA
transaction is rollbacked because of the SecurityException
, the changes performed by doB
are rollbacked as well. But if I let it in there, this is working as expected.
Am I doing something wrong or am I missing something?
Thanks!
Try to do not pass User instance in the doB(). Pass an Id instead and read the User from the repo internally. I am not sure how the attached entity is handled between the different sessions.