The Hibernate manual says that Query.list() is guaranteed not to return stale data. Is this also true for Criteria queries? I am consistently getting stale data from Criteria queries with Hibernate 3.5.2Final executing against SQLServer 2005.
The problem happens when users in different JVMs execute a list query, and then one of the users modifies one of the returned objects, and then both users re-execute the list query. The user who did not modify the data gets back stale information from his second list query.
The odd thing is that when I set show_sql to true, I can see that both sessions claim to be issuing the proper select for each list query, but the data that comes back to the second user's query from Hibernate is stale. I can even execute the query manually BEFORE the second user does to verify that the data has actually been changed, so there is clearly something wrong with the second user's session. Here is a code sample demonstrating the 4 points of execution:
Code:
// (1) User1 - session1/JVM1 - QUERY
Criteria q = session.createCriteria (Model.class).addOrder(Order.asc("created_at"));
List<Model> list = (List<Model>) q.list();
Model m = list.get(0); // Show to user -> not-stale
// (2) User2 - Session2/JVM2 - QUERY
Criteria q = session.createCriteria (Model.class).addOrder(Order.asc("created_at"));
List<Model> list = (List<Model>) q.list();
Model m = list.get(0); // Show to user -> not stale - yet
// (3) User1 - Session1/JVM1 - UPDATE
Model m = list.get(0);
m.setName("new-and-improved-name");
session.beginTransaction ();
session.save (m);
session.getCurrentTransaction ().commit ();
// ... Show modified object to user
// Manual database access shows the above changes
// (4) User2 - Session2/JVM2 - re-execute QUERY
Criteria q = session.createCriteria (Model.class).addOrder(Order.asc("created_at"));
List<Model> list = (List<Model>) q.list(); // Session2 user refreshes list
Model m = list.get(0); // m is STALE!!!! (actually all of list is stale...)
session.refresh (m); // m no longer stale.
It seems clear that somehow the Criteria query is caching data somehow - even when I have set session.setCacheMode(IGNORE), and session.setFlushMode(ALWAYS). Is there some other way to disable the Criteria.list() cache so that I always get current data back?
I have found that if I execute session.clear() at the start of step (4), then the second user will get non-stale objects back from the list query, but then accessing lazy associations on the returned objects causes exceptions.
Anyone have any clues??