Issue
- I have a
@Transactional
main service loading from repository an entity. - Then this service call a sub-service having
@Transactional(propagation = Propagation.REQUIRES_NEW)
loading the same entity to update one of its properties
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void updateEntity(Long id) {
repository.findById(id).get().setName("NEW NAME");
}
- Unfortunately, the update done from the sub-service is not visible from the main service, even if I try to reload the entity from repository and no matter which isolation level I choose (READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE).
Here is the code of the main service :
@Transactional
public void transactional() {
MyEntity myEntity1 = repository.findById(1L).get();
log.info("{} - {}", myEntity1, myEntity1.getName()); // "OLD NAME"
subService.updateEntity(1L);
MyEntity myEntity2 = repository.findById(1L).get();
log.info("{} - {}", myEntity2, myEntity2.getName()); // "OLD NAME" again, and same reference as myEntity1
}
Nevertheless, If I don't load once the entity in the main service before calling the sub-service, I DO see changes from the inner transaction.
@Transactional
public void transactional() {
subService.updateEntity(1L);
MyEntity myEntity2 = repository.findById(1L).get();
log.info("{} - {}", myEntity2, myEntity2.getName()); // "NEW NAME"
}
I guess what I want to achieve is not a standard way of doing things, but I really want to understand why if an entity is loaded once in an outer transaction, I can not retrieve changes from inner transaction(s).
Solution
After edition from the inner transaction, the entity must be explicitly reloaded inside the outer transaction by calling EntityManager#refresh
. (Thx to @M.Prokhorov for the clue)
entityManager.refresh(myEntity1);
As @Kayaman said in comment of my question:
It's the 1st level cache in action. It won't reload the entity (unless explicitly told to), since you've just loaded it.
Answered By - stephane brun
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.