Spring Data Jpa EntityManager refresh is not working

Viewed 1092

I want to apply external changes in Entity. so i used refresh() in EntityManager it is working in EntityManager session. but it's not working in external change.

it based on SpringBoot 2.x. this is my simple code.

@ExtendWith(SpringExtension.class)
@SpringBootTest
class RewardOrderRepositoryTest {
    @Inject
    private TestRepository testRepository;

    @PersistenceContext
    private EntityManager entityManager;

    @Test
    @Transactional
    @Rollback(false)
    public void test() {
        final Test test = testRepository.findById(8L).get();
        assertThat(test.getName(), is("Tom"));
        // BREAK POINT : name modify to external mysql client(ex) mysql workbench)
        entityManager.refresh(test);
        assertThat(test.getName(), is("Alice")); // it's false, still Tom.
    }
}

Why aren't external changes reflected? Is refresh() method only use in EntityManager Session?

1 Answers

This is caused by the transaction isolation level - MySQL's default is REPEATABLE READ:

This is the default isolation level for InnoDB. Consistent reads within the same transaction read the snapshot established by the first read. This means that if you issue several plain (nonlocking) SELECT statements within the same transaction, these SELECT statements are consistent also with respect to each other.

The test has started a transaction and so it will read the same data even though they have been changed in a different transaction.

You should be able to get the required behavior by explicitly setting the isolation level:

@Transactional(isolation=Isolation.ISOLATION_READ_COMMITTED)

Not tested on test methods: The isolation attribute seems to be unsupported on test methods according to javadoc of TransactionalTestExecutionListener.

Related