EntityManager.refresh not working?


I may be misunderstanding something. I want to update an entity with the latest fields from the database. When I call EntityManager.refresh(person), the entity doesn’t have the new values as I expect. I am not in a transaction. If I retrieve another copy with find, it does have the new values, but I want to use the original instance.

Person person = entityManager.find(Person.class, 1696L);
System.out.println("Person: " + person.getFirstName());
TimeUtilities.sleep(10000);    // The name is changed in another process during this time
entityManager.refresh(person);    // Should retrieve new name
System.out.println("Person: " + person.getFirstName());  // Shows old name
// Get the same record in another entity:
Person person2 = entityManager.find(Person.class, 1696L);
System.out.println("Person: " + person2.getFirstName());  // Shows new name

What am I missing?

The code doesn’t really make sense. If you use the same EntityManager, the Person#1696 will be added to the persistence context after the first find() call. A subsequent find() call will just return that existing instance without going to the database.
Refresh on the other hand will refresh the currently managed instance, and should actually throw an exception if the passed entity is not a managed instance.

So whatever your real code is doing, the example you are showing makes no sense.

Thanks for the response. My comment about another entity showed my confusion. person2 should be the same instance as person. But it wasn’t, and I guessed that was normal.

I pasted the code back in to my IDE to verify. In my little test case, I discovered that adding a refresh between two finds causes the second find to return a different instance, whether or not the record changed in the database. I verified in my debugger that they were separate instances.

Definitely weird behavior. I wonder if it has anything to do with level 2 cache. I tried to turn that off.

I tried simplifying my Person entity. I removed cascade-refresh on some @ManyToOne and @OneToOne fields, and the test code worked correctly.

It would be best if you could try to reproduce this with a test case(hibernate-test-case-templates/JPAUnitTestCase.java at main · hibernate/hibernate-test-case-templates · GitHub), and if you can, attach that to a new JIRA ticket in the issue tracker(https://hibernate.atlassian.net).

1 Like

I created a test case and got it to fail in hibernate 6.1 and 6.2, while it succeeded in 5.6

Then I noticed that I had a mis-configured bidirectional OneToOne relationship. After fixing that, it works.

Thanks for your help, beikov!

1 Like