Hi All,
I stumped with this issue recently and googled around, but can not find any answer till now. Below is description of the problem:
I have an entity named "operation". It has a timestamp field keeping track of creation timestamp, and a status field with possible values of "successful", "failed", "running".
A simplified version of the OperationDAOHibernateImpl is defined as below:
Code:
public class OperationDaoHibernateImpl implements OperationDao {
public Operation getLatest() {
... // get session logic omitted
return session.createQuery("from Operation order by timestamp desc").uniqueResult();
}
public Operation getLatestSuccessful() {
... // get session logic omitted
return session.createQuery("from Operation where status='successful' order by timestamp desc").uniqueResult();
}
}
My web application uses OSIV pattern and the request cycle involves below steps
1. load the latest operation by calling operationDao.getLatest() and do something with it.
2. load the latest successful operation by calling operationDao.getLatestSuccessful() and do something with it.
As I am using OSIV pattern, these two steps will be executed in the same hibernate session. Now assume status of the latest operation is changed from "running" to "successful" at the time between step 1 and step 2 by another transaction. The returned object of step 2 will have status of "running" althought where clause of the query states that it wants to retrieve the successful operation due to the fact that hibernate query tries to use cached object in the session which in this case is loaded by step 1.
Using cached object with obsolete state is fine since it does not harm the application generally. However in this case, it breaks the where clause contract and thus breaks "getLatestSuccessful" contract, and could cause big problems for API users as they natually think that the query result should obey to where clause of the query.
What do you think about this issue? Clearing session in getLatestSuccessful method is not preferable as it prevents lazy loading of other objects which breaks my intension of using OSIV pattern. Does the query has an option of bypassing the entity in the first level cache and get object directly from database? (query does have a option of CacheMode.REFRESH, but it is for second-level cache misably).
Regards
Robin