JPA createQuery and flush / clear

The following code works, however, if I remove the calls to flush () and clear (), then the second call to showTable () does not display the updated name "joan", but "john".

What is the correct way to achieve this without calling flush () and clear ()?

import java.util.List; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import javax.persistence.Query; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests; import org.springframework.test.context.transaction.TransactionConfiguration; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import com.example.Customer; @ContextConfiguration(locations = {"classpath:spring/test/spring-test.xml"}) @TransactionConfiguration(transactionManager = "txManager") public class Test extends AbstractTransactionalJUnit4SpringContextTests { private final Logger log = LoggerFactory.getLogger(getClass()); @PersistenceContext private EntityManager entityManager; @Test @Transactional(propagation = Propagation.REQUIRES_NEW) public void test() throws Exception { Customer customer = new Customer(); customer.setName("john"); entityManager.persist(customer); entityManager.flush(); entityManager.clear(); showTable(); final Query query = entityManager.createQuery("update Customer c set c.name='joan'"); int updateCount = query.executeUpdate(); log.debug("Update count: " + updateCount); entityManager.flush(); entityManager.clear(); showTable(); } public void showTable() { final Query query = entityManager.createQuery("select c FROM Customer c"); List<Customer> list = query.getResultList(); for (Customer customer: list) { log.info("customer name: " + customer.getName()); } } } 
+4
source share
1 answer

The first test does not need to be cleaned up or cleaned up, because the entity manager must detect that the expected changes will not be saved. Therefore, before executing the request, you will not need to clear () and even less clean ().

The second test, however, is different. You execute the update request, and thoses requests completely bypass the first level cache. They make changes to the database behind her. This is why you need to clear it: if you do not, the select query will find a client that is already in the cache, and an object with a cache (but outdated) will be returned.

+5
source

Source: https://habr.com/ru/post/1414924/


All Articles