I'm currently facing an issue with two methods of the same Spring service, here's a basic example:
@Transactional(readOnly = true)
public Optional<SomeEntity> readSomeEntity(string idEntity) {
return this.someEntityRepository.findById(idEntity);
}
@Transactional
public Optional<SomeEntity> readOrCreateSomeEntity(SomeEntity entity) {
if (this.someEntityRepository.existsById(entityInfo.getId()) {
// How to make so that this call goes through the Spring Proxy and actually
// gets @Transactional(readOnly = true) applied ?
return this.readSomeEntity(entityId.getId());
}
else {
return Optional.of(this.someEntityRepository.save(entity));
}
}
How to actually make sure that during the @Transactional (not read-only) context of readOrCreateSomeEntity, the actual call of readSomeEntity is purely wrapped in a readonly transactional context? And that the Transactional context of readOrCreateSomeEntity is not propagated?
I thought about two options here:
- Use a self reference
@Autowired MyService self. But this is an issue because it results in a circular reference and a context instanciation error. - I also thought about
@Transactional(readOnly = true, propagation = Propagation.REQUIRES_NEW), but it won't even be handled by Spring since I'm not calling thereadSomeEntitymethod through the proxy!
Is it possible to achieve this, and if so, is it only possible through self reference?
From a purely technical standpoint I would prefer that the readSomeEntity is indeed 100% read-only, because hey, it's a readonly method, and I don't get why Spring would propagate its not readonly transactional context to the read submethod.. Am I wrong thinking like this?
In the end, should I care about this? Is it too much to enforce that this reading method actually does not do updates by 100% wanting a read only transactional context?
Thanks for your insight.
You have to put
in a separate bean unlikly. transactional method called in the same class don't use the proxy at all I think.
Anyway I don't see any benefits in doing this. Why you don't save directly the entity in the other method?