-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 3 posts ] 
Author Message
 Post subject: Null value cannot be cache using hibernate
PostPosted: Sun Oct 12, 2008 4:58 am 
Newbie

Joined: Sat Oct 11, 2008 12:48 pm
Posts: 5
I'm using Hibernate with 2nd level cache using Ehcache. I found that if the result returned from session.get() (searching by primary key) is NULL, the value will not be cached in both 1st level and 2nd level cache and SQL will be fired to database again. There is no problem if the value returned is not null for the same entity.

I have debug using the hibernate and ehcache source and I'm sure that the cache is enabled and called properly. Here are my findings of the problem:
In the EntityLoader(Loader).initializeEntitiesAndCollections method, if there is no result returned from database, the hydratedObjects is empty. So the method TwoPhaseLoad.initializeEntity (which will put the result into the cache) will never be called.

Code:
EntityLoader(Loader).initializeEntitiesAndCollections(...)
...
for ( int i = 0; i < hydratedObjectsSize; i++ ) {
...TwoPhaseLoad.initializeEntity(...)


Code:
TwoPhaseLoad.initializeEntity(...)
...persister.getCache().put(...


Actually the null value is expected to be cached also as the same criteria will always return null, no matter how many times I called to database.

I have browser all hibernate and ehcache documentation and forum and no related config is available. Ehcache ifself support null value for caching. There is also no documentation saying that null value from session.get() cannot be cached. Actually, I have post to JIRA Issue tracking system but is rejected with unknown reason.
http://opensource.atlassian.com/project ... e/HHH-3522

In our system, we will redirect the request to other system based the existence of customerId in our system. So, if NULL value cannot be cached, there will be a large number of redundant SQLs fired to database which will greatly affect our performance.

Do anyone have solution for this situation? Thanks all for your help!

Hibernate version:
3.2.5
Mapping documents:
N/A
Full stack trace of debug that comes to point of failure:
Code:
EntityLoader(Loader).initializeEntitiesAndCollections(List, Object, SessionImplementor, boolean) line: 848   
EntityLoader(Loader).doQuery(SessionImplementor, QueryParameters, boolean) line: 729   
EntityLoader(Loader).doQueryAndInitializeNonLazyCollections(SessionImplementor, QueryParameters, boolean) line: 236   
EntityLoader(Loader).loadEntity(SessionImplementor, Object, Type, Object, String, Serializable, EntityPersister) line: 1860   
EntityLoader(AbstractEntityLoader).load(SessionImplementor, Object, Object, Serializable) line: 48   
EntityLoader(AbstractEntityLoader).load(Serializable, Object, SessionImplementor) line: 42   
SingleTableEntityPersister(AbstractEntityPersister).load(Serializable, Object, LockMode, SessionImplementor) line: 3044   
DefaultLoadEventListener.loadFromDatasource(LoadEvent, EntityPersister, EntityKey, LoadEventListener$LoadType) line: 395   
DefaultLoadEventListener.doLoad(LoadEvent, EntityPersister, EntityKey, LoadEventListener$LoadType) line: 375   
DefaultLoadEventListener.load(LoadEvent, EntityPersister, EntityKey, LoadEventListener$LoadType) line: 139   
DefaultLoadEventListener.proxyOrLoad(LoadEvent, EntityPersister, EntityKey, LoadEventListener$LoadType) line: 195   
DefaultLoadEventListener.onLoad(LoadEvent, LoadEventListener$LoadType) line: 103   
SessionImpl.fireLoad(LoadEvent, LoadEventListener$LoadType) line: 878
SessionImpl.get(String, Serializable) line: 815   
SessionImpl.get(Class, Serializable) line: 808



Name and version of the database you are using:
Oracle10g[/code]


Top
 Profile  
 
 Post subject:
PostPosted: Sun Oct 12, 2008 6:12 am 
Expert
Expert

Joined: Fri Jul 13, 2007 8:18 am
Posts: 370
Location: london
My understanding is that the second level cache is just a cache of objects so I would expect this behaviour. What you're describing is a query cache, i.e. to remember that the result of querying for an object by its ID returned null.

So instead of doing a get(id) use an explicit query to find the object by its ID and set the cacheable flag on that query:
Code:
createQuery("from Entity where id=:id").setLong("id",id).setCacheable(true).uniqueResult();


Top
 Profile  
 
 Post subject:
PostPosted: Sun Oct 12, 2008 9:36 pm 
Newbie

Joined: Sat Oct 11, 2008 12:48 pm
Posts: 5
Thanks for your reply.

But how about the first level cache? I would expect the NULL value would be cached in first level cache if I'm calling session.get(id). But from my debug, it will not be cached in first level cache also. Do I misuse the session.get(id) or any configuration needed?

Actually, I am not doing a query cache. I'm using session.get(id) to get the object by primary key. And I think hibernate would then cache the result in first level cache even there is no second level cache enabled. Hope that my understanding is correct.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 3 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.