stephane brun
stephane brun

Reputation: 264

Outer transaction can not retrieve changes from inner transaction if entity already loaded once

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void updateEntity(Long id) {

        repository.findById(id).get().setName("NEW NAME");
    }

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).

Upvotes: 0

Views: 634

Answers (1)

stephane brun
stephane brun

Reputation: 264

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.

Upvotes: 1

Related Questions