-->
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: ehcache as hibernate second level cache: queries
PostPosted: Fri Feb 15, 2008 4:40 am 
Newbie

Joined: Fri Feb 15, 2008 4:24 am
Posts: 5
Hi
In our company we have an application that has complex object graphs where one hibernate persistent object refers to another hibernate persistent object. I want to use ehcache as my secon level cache

Now the first question is say I have all the objects in the database loaded in my second level cache.

Now if I query Hibernate using any [b]non-id [/b] field, though the second level cache has got those objects , still I think the query would hit the database as it never knows whether all the objects the query should match are in the second level cache or not. I want to make my objects eternal. So is there any way to let hibernate know, that I have all the data in my cache and it does not need to look in the database even when I query with a non-id field?


Top
 Profile  
 
 Post subject: Query Cache?
PostPosted: Sun Feb 17, 2008 8:08 pm 
Beginner
Beginner

Joined: Thu Jun 23, 2005 10:23 pm
Posts: 22
I'm wondering if the Query Cache would help you - you might want to look into that. I found this good read: http://www.javalobby.org/java/forums/t48846.html


Top
 Profile  
 
 Post subject: Re: Query Cache?
PostPosted: Sun Feb 17, 2008 9:22 pm 
Expert
Expert

Joined: Wed Apr 11, 2007 11:39 am
Posts: 735
Location: Montreal, QC
wiphillyfan wrote:
I'm wondering if the Query Cache would help you - you might want to look into that. I found this good read: http://www.javalobby.org/java/forums/t48846.html



Query cache is indeed a solution but a better solution would be fetching database ids instead of entities. The reason behind this is that a query cache is thrown away if hibernate detects any update in any participating entities in a query so updating a single entity will result in hitting the database and fetching the whole object graph. Retrieving ids is minimal and combined with a query cache gives the ultimate performance.


Farzad-


Top
 Profile  
 
 Post subject: Re: Query Cache?
PostPosted: Sun Feb 17, 2008 11:30 pm 
Newbie

Joined: Fri Feb 15, 2008 4:24 am
Posts: 5
[quote="farzad"][quote="wiphillyfan"]I'm wondering if the Query Cache would help you - you might want to look into that. I found this good read: http://www.javalobby.org/java/forums/t48846.html[/quote]


Query cache is indeed a solution but a better solution would be fetching database ids instead of entities. The reason behind this is that a query cache is thrown away if hibernate detects any update in any participating entities in a query so updating a single entity will result in hitting the database and fetching the whole object graph. Retrieving ids is minimal and combined with a query cache gives the ultimate performance.


Farzad-[/quote]

Dear Farzad
Thanks a lot for the reply. But I am afraid that I probably could not make my doubt clear.

1) I am not looking for the query cache as a solution as my database tables get updated too quickly to get benefit from it
2) I am fine with fetching objects with ids. But in our application the client wants to read objects based on their Date fields, which are certainly non-unique non-id property fields.

My problem more precisely is:

I work in a software product company, and we use hibernate in our java based application . The application is a smart-client based application where each client is itself a jvm . We were using our proprietary cache bor both client and server side now , but want to replace the server side cache with a cache solution that supports clustering.

Now we are trying to use ehcache as the hibernate second level cache and trying to know if we can replace our current cache with it . But some technical problems are coming up. The client tries to read our objects mainly based on its date fields which obviously is not a unique key . In our current in memory cache , we were maintaining a date list
to make the server side program know, which objects are there in the cache. eg. If client wants to read all objects with date as Feb 16 2008, the server side program checks if the date is included in the date list and if included, it simply loops through the object arraylist stored to filter out the needed objects. So database hit is avoided.

But, I think that in hibernate, if I query for objects with non-id field it anyway would search in the database (kindly do not consider the query level cache, but only the cache of persistent objects). Is there any way, to query the ehcache so that it only gives all the objects in the cache only , without going to database. i.e I want to force hibernate to look into the cache only , as I can make my objects stored in ehcache eternal, and know that if the datelist has the requested date, then I have all the objects
corresponding to it already in cache?


Top
 Profile  
 
 Post subject: Re: Query Cache?
PostPosted: Mon Feb 18, 2008 12:04 am 
Expert
Expert

Joined: Wed Apr 11, 2007 11:39 am
Posts: 735
Location: Montreal, QC
Query cache is still your answer, but you have to make sure that you set the query to be cachable. For the record, I explain what happens in your case. Lets say you have and Order which has an orderDate. So your query would be something like:

Code:
select o from Order o where o.orderDate = ?


for the first time for a given data X hibernate goes to database and finds the results but it stores the result in cache for this query and parameter X. So if the query name is Q1 and the parameter is X1, hibernate creates a new cache entry [Q1, X1] and stores the results. Next time when you do a query with Q1 and the same X1 hibernate is not going to consult database for the results. You can also instruct ehcache to keep the results forever. This is transparent to hibernate. However, your query cache is going to be constructed as needed, by which I mean if you have dates X1, X2, X3, ...., Xn then hibernate will go to database n times.

One thing I am not sure here though is how hibernate stores the results in the cache. It could be hibernate only stores the ids of the results and it goes to cache again when an instance is needed. I have a feeling this is not the case, and hibernate stores the values. This is important to consider because in certain cases hibernate decides to invalidated a query's cached results. For example, updating any Order object will cause any Q1's cache to be invalidated. In such a scenario, the next time a request for [Q1, X1] will cause a database select command which might be heavy since everything will be fetched again. My suggestion here is that you only fetch the ids:

Code:
select o.id from Order o where o.orderDate = ?


and then get each object one by one. The improvement here is that if an Order is updated it is already in the cache and the query itself is lightweight since it is only returning ids. The drawback here is that the first time the cache is constructed there will quite a few selects which will definitely slow down the first access. This is a decision you will have to make according to your use cases.


Let me know if you have more concerns.

Farzad-


Top
 Profile  
 
 Post subject: Re: Query Cache?
PostPosted: Mon Feb 18, 2008 12:06 am 
Expert
Expert

Joined: Wed Apr 11, 2007 11:39 am
Posts: 735
Location: Montreal, QC
Bahata wrote:
1) I am not looking for the query cache as a solution as my database tables get updated too quickly to get benefit from it



and by the way, how does your database get updated? Is it through a hibernate session or it is done somewhere outside the scope of a hibernate session?



Farzad-


Top
 Profile  
 
 Post subject: Re: Query Cache?
PostPosted: Mon Feb 18, 2008 3:30 am 
Newbie

Joined: Fri Feb 15, 2008 4:24 am
Posts: 5
[quote="farzad"]Query cache is still your answer, but you have to make sure that you set ... My suggestion here is that you only fetch the ids:

[code]select o.id from Order o where o.orderDate = ?[/code]

and then get each object one by one. The improvement here is that if an Order is updated it is already in the cache and the query itself is lightweight since it is only returning ids. The drawback here is that the first time the cache is constructed there will quite a few selects which will definitely slow down the first access. This is a decision you will have to make according to your use cases.


Let me know if you have more concerns.

Farzad-[/quote]

Dear Farzad
Thank you so much for your reply. Actually I have found a good work-around for my problem already in a different way. But as an answer to your last paragraph:

Yes you are right. If I take only IDs as result then the query would be light-weight .

My work-around is that I can create a new object say DateList, where it has date as its unique id and maps to date_list table having date as primary key. My other objects that need to be fetched acc. to date can have their tables refer to the date field of date_list table as foreign key.
DateList object would have a one-to-may collection set of these objects. I would just fetch the DateList object to read objects for a date. As date has become id now, hibernate would first look into its second level cache for them.


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.