]
Sanne Grinovero commented on HSEARCH-961:
-----------------------------------------
Anders,
thank you so much, that's an excellent analysis; I look forward to see more issues
from you!
ObjectNotFoundException not caught in FullTextSession for deleted
objects
-------------------------------------------------------------------------
Key: HSEARCH-961
URL:
http://opensource.atlassian.com/projects/hibernate/browse/HSEARCH-961
Project: Hibernate Search
Issue Type: Bug
Components: query
Affects Versions: 3.4.1.Final
Environment: Hibernate 3.6.7
EHCache 1.2.4 and 2.4.6 in Read-write mode.
MS SQL Server 2000
async indexing.
Reporter: Anders Soee
Assignee: Sanne Grinovero
Priority: Minor
Fix For: 3.4.2, 4.0.0.CR2
Experienced behavior:
1: Show page with search results.
2: Delete one
3: Redirect back to the previous search.
4: Sometimes (about 1 in 10), the search fails with an ObjecNotFoundException.
Expected behavior:
As experienced, minus the exceptions.
My analysis:
Since the indexing is asynchronous, there will be a short period, where the search will
include the deleted item.
If the entities where not cached, this should not be a problem, since they would simply
not be included in the IN query.
In this case, however, all the entities are cached by EHCache in read-write mode.
I have identified the problem to be in SecondLevelCacheObjectsInitializer:
{code}
65: final boolean isIn2LCache = session.getSessionFactory().getCache().containsEntity(
entityInfo.getClazz(), entityInfo.getId() );
66: if ( isIn2LCache ) {
67: //load the object from the second level cache
68: session.get( entityInfo.getClazz(), entityInfo.getId() );
69: }
{code}
Line 68 is where the exception occurs.
It appears that cache.containsEntity() is not a guarantee that the entity can actually be
loaded.
In fact, in EHCache a lock object is placed in the cache when the item is deleted, and
never removed again.
Thus the cache contains "something", just not a loadable entity.
My suggestion:
Wrap session.get() with a try-catch block, and ignore ObjectNotFoundException's (and
probably EntityNotFoundException too, for JPA).
My workaround:
Manually evicting the entity from the 2nd level cache when deleting it.
Stacktrace:
org.hibernate.ObjectNotFoundException: No row with the given identifier exists:
[com.jysk.resmgr.model.Resource#5663]
at
org.hibernate.impl.SessionFactoryImpl$2.handleEntityNotFound(SessionFactoryImpl.java:435)
at
org.hibernate.event.def.DefaultLoadEventListener.returnNarrowedProxy(DefaultLoadEventListener.java:320)
at
org.hibernate.event.def.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:277)
at
org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:152)
at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:1090)
at org.hibernate.impl.SessionImpl.get(SessionImpl.java:1005)
at org.hibernate.impl.SessionImpl.get(SessionImpl.java:998)
at
org.hibernate.search.query.hibernate.impl.SecondLevelCacheObjectsInitializer.initializeObjects(SecondLevelCacheObjectsInitializer.java:68)
at
org.hibernate.search.query.hibernate.impl.PersistenceContextObjectsInitializer.initializeObjects(PersistenceContextObjectsInitializer.java:81)
at
org.hibernate.search.query.hibernate.impl.MultiClassesQueryLoader.executeLoad(MultiClassesQueryLoader.java:135)
at
org.hibernate.search.query.hibernate.impl.AbstractLoader.load(AbstractLoader.java:72)
at
org.hibernate.search.query.hibernate.impl.FullTextQueryImpl.list(FullTextQueryImpl.java:208)
--
This message is automatically generated by JIRA.
For more information on JIRA, see: