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:
- Find an object with my JPA class (row in the database with a particular id)
- update a boolean flag on the object (tinyint field in the database)
- persist the object
- 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
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.
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?
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.
精彩评论