views:

54

answers:

4

Hi,

I am working with JPA (1.0 or 2.) + hibernate (3.4.0 or 3.6.0) and I have run into a problem with I think caching somewhere. What I do:

  1. Find an object with my JPA class (row in the database with a particular id)
  2. update a boolean flag on the object (tinyint field in the database)
  3. persist the object
  4. grab the entire table from the database with getResultList() hoping to have the change reflected.

Problem:

The change is reflected with getResultList the first time I call it, but the second time it show the previous state. The third time it shows correctly; the fourth, the previous state; etc. It seems to alternate between the two state each time I call getResultList on the table.

Some code for #3 above:

EntityTransaction entityTransaction = entityManager.getTransaction();
entityTransaction.begin();
entityManager.persist(object);
entityTransaction.commit();
entityManager.refresh(object);

Code for #4:

Query query = entityManager.createQuery("from " + object.getName());
List<T> resultList = query.getResultList();

In my efforts to solve the problem, I have:

1.Turned L2 and query cache off in the persistence.xml with:

<property name="hibernate.cache.use_query_cache" value="false"/>
<property name="hibernate.cache.use_second_level_cache" value="false"/>

2.forced a cache eviction before running getResultList() with (using JPA 2.0):

entityManager.getEntityManagerFactory().getCache().evictAll()

3.tried calling refresh() all over the place - to no effect.

Am I missing something?

Any help would be appreciated.

Thanks, sop

A: 

I don't think entityManager.refresh(object); is necessary. The default flush mode is Auto, so EntityManager will flush (synchronize the persistence context to the underlying database) at query execution.

Furthermore, does each query entail a SQL query from the database?

Kevin Yang
+1  A: 

I have encountered this issue before (or something very similar) with a few different JPA providers. Make sure that you are explicitly closing your EntityManagers.

Steven Benitez
How could this affect anything?? Persistence context are isolated.
Pascal Thivent
Pascal: I'm not quite sure either, but I was encountering a very similar issue with both EclipseLink and Hibernate and stale data alternating with fresh data and I tried the very same things that someOnePerson tried (disabling second level cache, query cache, explicitly evicting cache, etc.) and when I finally began closing my EntityManagers the problem went away instantly and has never recurred. I was hopeful it would have helped here too, since the description of the problem was nearly identical.
Steven Benitez
I suspect another implementation problem.
Pascal Thivent
A: 

In answer to Steven:

I just made sure that I am closing the EntityManager explicitly after the persisting of the object. No effect. Alternating behaviour is still the same.

I also made sure the EntityManager is closed after the initial find of the object. But afterwards when trying to persist the object with the new data set, I get the error:

detached entity passed to persist

I tried using merge() after this, but I get back to the initial problem again.

someOnePerson
A: 

Well, Steven, actually your solution did finally end up helping. In my application, I call my updating methods from a Servlet. The problem went away as soon as I closed the EntityManager before I called any of my methods. I still don't know why this works.

Upon closer inspection of the problem, I found that it wasn't getResultList() that was the problem, but when I did a find() on the object in question after updating it, that find() would alternate between two objects with different hashes but same IDs (the different hash was a result of the boolean flag being set or not.)

This is still really weird, but Steven's suggestion worked once I found the right place to do it.

someOnePerson
I have no idea how all this is implemented the whole thing but having to "close an EntityManager before calling any method" is certainly not right. You have an underlying issue and you're only working around it.
Pascal Thivent