-->
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.  [ 7 posts ] 
Author Message
 Post subject: HQL query does not use second level cache
PostPosted: Mon Mar 03, 2008 1:22 pm 
Newbie

Joined: Tue May 22, 2007 10:52 am
Posts: 13
I have enabled second level cache for an entity. If I use entityManager.find to retrieve the entity by PK, the cache works (i.e. it hits the DB only the first time).

But if I make a HQL query on this entity, it hits the DB every time...

Here is the entity:

Code:
@Entity
@Table(name = "CORE_MessageBuyerTranslation", uniqueConstraints = {})
@Cache(usage=CacheConcurrencyStrategy.NONSTRICT_READ_WRITE, region="com.ibx.ibxrequest.model.CoreMessageBuyerTranslation")
public class CoreMessageBuyerTranslation implements java.io.Serializable {
...
}


and here is the HQL that hits the DB every time:

Code:
      List<CoreMessageBuyerTranslation> translatedKeys = entityManager.createQuery(
            "from CoreMessageBuyerTranslation mbt "
            + "WHERE mbt.coreBuyer = :coreBuyer "
            + "  AND mbt.coreLang = :coreLang "
            + " AND mbt.coreMessage.messageKey = :messageKey")
            .setParameter("coreBuyer", buyer)
            .setParameter("coreLang", lang)
            .setParameter("messageKey", key)
            .getResultList();


Why does it hit the DB every time? Shouldn't it use the cache?

Thanks,


Top
 Profile  
 
 Post subject: Second level cache
PostPosted: Tue Mar 04, 2008 6:22 am 
Newbie

Joined: Mon Jan 02, 2006 6:12 am
Posts: 6
The second level cache is only used when accessing the object by id (pk), such as using session.get, session.load or navigating the object graph (ex Cat cat = kitten.getCat()). Searching for entities based on other attributes does not use the second level cache.


Top
 Profile  
 
 Post subject: Re: Second level cache
PostPosted: Wed Mar 05, 2008 8:12 am 
Newbie

Joined: Tue May 22, 2007 10:52 am
Posts: 13
peter.knuts wrote:
The second level cache is only used when accessing the object by id (pk), such as using session.get, session.load or navigating the object graph (ex Cat cat = kitten.getCat()). Searching for entities based on other attributes does not use the second level cache.


Actually the above is wrong. second level cache should work with HQL as well. Here is an excerpt from hibernate docs:

Code:
Whenever you pass an object to save(), update()  or saveOrUpdate() and whenever you retrieve an object using load(), get(), list(), iterate() or scroll(), that object is added to the internal cache of the Session.


Here is the doc:
http://www.hibernate.org/hib_docs/v3/reference/en/html_single/#performance-sessioncache

Can anybody please help


Top
 Profile  
 
 Post subject:
PostPosted: Wed Mar 05, 2008 8:56 am 
Regular
Regular

Joined: Mon Aug 06, 2007 10:49 am
Posts: 67
Location: Banska Bystrica, Slovakia
did u try this?
Code:
session.createQuery("query").setCacheable(true);


Top
 Profile  
 
 Post subject:
PostPosted: Wed Mar 05, 2008 9:46 am 
Newbie

Joined: Tue May 22, 2007 10:52 am
Posts: 13
ferozz wrote:
did u try this?
Code:
session.createQuery("query").setCacheable(true);


The above is about the query cache, but I am interested in the entity cache. Query cache does not solve my problem.


Top
 Profile  
 
 Post subject: Second level cache
PostPosted: Wed Mar 05, 2008 9:56 am 
Newbie

Joined: Mon Jan 02, 2006 6:12 am
Posts: 6
Hi again. First of all, that doc part is about the first level cache that helps manage object identity for the duration of the hibernate session. It is however true that even the second level cache (bound to the session factory) is updated based on most of theese conditions. This does not however mean that you can find an object in the cache based on an arbitary hql query.

It is possible to find an object in the cache based on a business key (not the same as the primary key). The attributes of the business key is normally composed of the attributes within the equals and hash code.

It is also possible to use a query cache. If the (exact) same query is executed more than once, the result of the query can be cached. Remember that the query cache expires on every insert, updated and delete from the affected table(s). Maybe this is what you are looking for?

The second level cache does not normally contain every entity in the database. Even if you did find one or more entities based on your example query, the cache can never guarantee that there are no other object in the database mathing your query.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Mar 05, 2008 12:54 pm 
Newbie

Joined: Wed Mar 05, 2008 4:50 am
Posts: 3
Hi,
as far as I know (and as previous poster pointed) entity cache is searched when you try to retrieve entity by its id. that includes entitymanager.find() or retrieving entities referenced from other entities.
In the query you check specific fields, so id-based cache wont help much here. You need query cache.
This needs:
Quote:
session.createQuery("query").setCacheable(true);


as well as hibernate properties set
hibernate.cache.use_second_level_cache=true
hibernate.cache.use_query_cache=true

as well as @Cache-enabling of any @Entities among:
CoreBuyer
CoreLang
CoreMessage
MessageKey
and any further entities referenced from them

Best regards
Jakub


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 7 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.