The em.refresh(person)
in the following code does not work. Rather than refreshing the person
with a fresh value from database, it resets (undo or discards) the changes made in the cache. I am not able to understand why?
em.getTransaction().begin();
Person person = em.find(Person.class, 2L); //Person[id=2L, age=23]
person.setAge(24);
System.out.println(person.getAge()); //it prints 24
//Person with id=2 in database gets modified concurrently somehow,
//its age becomes 25 in PERSON table (by an SQL update for example "UPDATE person SET age=25 WHERE id=2")
em.refresh(person); // attempts to load fresh value from database with a SELECT...
System.out.println(person.getAge()); //it prints 23, rather than 25, why?
em.getTransaction().commit();
em.close();
Could someone help me understand this behavior by the refresh()
method of EntityManager
?
If you want to see changes made from other transactions while inside a transaction you need to change the isolation level to READ_COMMITTED
<property name="hibernate.connection.isolation">TRANSACTION_READ_COMMITTED</property>
A few definitions to clarify the discussion:
person.setAge(24);
) are not visible by the database until they are flushed. A flush occurs when calling em.flush, committing or, typically, when executing a query such as select * from Person where name=...
but not when calling refresh()So basically: