-->
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: Level 2 cache questions
PostPosted: Mon Jun 13, 2011 11:55 am 
Newbie

Joined: Wed Mar 30, 2011 10:22 pm
Posts: 10
Hello, everybody!
There are couple (at least) things about second level cache I don't understand.
I'd appreciate if someone clears it out.
1. In my application I use queries like this

from Something where id in (:ids)

Let's say I'm asking for objects with ids 1,2,3 which are in cache. Is hibernate smart enough to get them directly from cache? Or it will go to the database?

2. In some queries I override lazy loading and use join fetch:

select s from something s left join fetch s.children where s.id= 123

If all objects (both Something s and children) are in cache will hibernate use it? Or it will go to the database?

Thank you,
Andrey


Top
 Profile  
 
 Post subject: Re: Level 2 cache questions
PostPosted: Tue Jun 14, 2011 3:07 am 
Expert
Expert

Joined: Tue Jun 16, 2009 3:36 am
Posts: 990
answer to question 1:
It will go to the database, even if objects with ids 1,2,3 are already in cache.
There exists only one scenario, where this query don't will hit the database:
a) you enabled also the second-level-query-cache
b) you already did execute the same query (from Something where id in (1,2,3)) with specifying
query.setCacheable(true) before executing it.
c) After the first execution of the query (=the one which did hit the database and fill the second-level-query-cache) the table Something were not object to any modification. This because any insert/delete/update action in the involved table makes hibernate consider obsolete the cached query result set.
d) the second-level-query-cache is not expired.
e) the actual query is executed again with query.setCacheable(true)

If all this conditions are true, then the query should'nt hit the database.


answer to question 2:
The same thing as with question 1 with the difference that in this case 2 tables are involved,
so any change in something or children table will convert obsolete your cached result-set.


Top
 Profile  
 
 Post subject: Re: Level 2 cache questions
PostPosted: Tue Jun 14, 2011 7:51 am 
Newbie

Joined: Tue Jun 14, 2011 7:50 am
Posts: 1
hellow gud eve .. asian food store - online consignment - designer consignment

_________________
asian food store - online consignment - designer consignment


Top
 Profile  
 
 Post subject: Re: Level 2 cache questions
PostPosted: Tue Jun 14, 2011 10:09 am 
Newbie

Joined: Wed Mar 30, 2011 10:22 pm
Posts: 10
pb00067 wrote:
answer to question 1:
It will go to the database, even if objects with ids 1,2,3 are already in cache.
There exists only one scenario, where this query don't will hit the database:
a) you enabled also the second-level-query-cache
b) you already did execute the same query (from Something where id in (1,2,3)) with specifying
query.setCacheable(true) before executing it.
c) After the first execution of the query (=the one which did hit the database and fill the second-level-query-cache) the table Something were not object to any modification. This because any insert/delete/update action in the involved table makes hibernate consider obsolete the cached query result set.
d) the second-level-query-cache is not expired.
e) the actual query is executed again with query.setCacheable(true)

If all this conditions are true, then the query should'nt hit the database.


answer to question 2:
The same thing as with question 1 with the difference that in this case 2 tables are involved,
so any change in something or children table will convert obsolete your cached result-set.

Thank you very much. It looks like if I don't enable query cache the second level cache is pretty much useless. In what scenario (if query cache is off) second level is used?
And one more thing. As I already wrote I get objects from data base by their ids. But every time those ids are different. In one query I may have
1,2,3 in another 2,1,3. The same objects, but different queries. So, probability I have exactly the same query is very low. It means query cache is not useful.
Any ideas how can I improve performance in such case?

Thank you,
Andrey


Top
 Profile  
 
 Post subject: Re: Level 2 cache questions
PostPosted: Thu Jun 16, 2011 5:42 am 
Expert
Expert

Joined: Tue Jun 16, 2009 3:36 am
Posts: 990
Quote:
In what scenario (if query cache is off) second level is used?


There are 2 main scenarios where the second level without query-cache turns useful:
    1. Entity retrieval.
    a) by identifier
    Code:
    Something something = entityManager.find(Something.class, new Long(1));  // or session.get(Something.class, new Long(1));

    If you know the identifier of a determinate entity object, you can get the entity without hitting the database,
    when the entity is cached in 2L-cache.

    b) navigations with relation cardinaliy 1 (=ToOne).
    Assuming you defined a 'father' role for Something and Father class is also declared for 2L-cache,
    then the following navigation don't produces a database hit, if the regarding father entity is already cached:
    Code:
    Father myfather = something.getFather();


    2. Collection cache
    Collection cache is in my opinion the very powerful feature of Hibernate's 2L-cache, because it prevent database hits
    on navigations with cardinality > 1 (=ToMore) .
    If you i.e. declare both entity classes "something" and "children" the be cached in 2L-cache and the relation "something" towards "children" as well, then following code executed more times will no more hit the database a second time, even if you are in different sessions (as long you don't change the content of this collection).
    Code:
    Something something = entityManager.find(Something.class, new Long(1));  // or session.get(Something.class, new Long(1));
    Collection childrens = something.getAllChildren();
       




Top
 Profile  
 
 Post subject: Re: Level 2 cache questions
PostPosted: Thu Jun 16, 2011 5:54 am 
Expert
Expert

Joined: Tue Jun 16, 2009 3:36 am
Posts: 990
Quote:
Any ideas how can I improve performance in such case?


Define classes "something" and "children" the be cached in 2L-cache and their relation "something" towards "children" as well.
Then instead to use user-queries to retrieve the something objects with its childrens, use entityManager.find and navigation only where possible:

Code:
Integer[] mysomethings = new Integer[] {1,2,3};  // or {3,2,1}
for (Integer i : mysomethings) {
               Something something = entityManager.find(Something.class, i);
               Collection childrens = something.children();
               // do your work
}


Top
 Profile  
 
 Post subject: Re: Level 2 cache questions
PostPosted: Thu Jun 16, 2011 12:08 pm 
Newbie

Joined: Wed Mar 30, 2011 10:22 pm
Posts: 10
pb00067 wrote:
Quote:
In what scenario (if query cache is off) second level is used?


There are 2 main scenarios where the second level without query-cache turns useful:
    1. Entity retrieval.
    a) by identifier
    Code:
    Something something = entityManager.find(Something.class, new Long(1));  // or session.get(Something.class, new Long(1));

    If you know the identifier of a determinate entity object, you can get the entity without hitting the database,
    when the entity is cached in 2L-cache.

    b) navigations with relation cardinaliy 1 (=ToOne).
    Assuming you defined a 'father' role for Something and Father class is also declared for 2L-cache,
    then the following navigation don't produces a database hit, if the regarding father entity is already cached:
    Code:
    Father myfather = something.getFather();


    2. Collection cache
    Collection cache is in my opinion the very powerful feature of Hibernate's 2L-cache, because it prevent database hits
    on navigations with cardinality > 1 (=ToMore) .
    If you i.e. declare both entity classes "something" and "children" the be cached in 2L-cache and the relation "something" towards "children" as well, then following code executed more times will no more hit the database a second time, even if you are in different sessions (as long you don't change the content of this collection).
    Code:
    Something something = entityManager.find(Something.class, new Long(1));  // or session.get(Something.class, new Long(1));
    Collection childrens = something.getAllChildren();
       




Thank you very much!
The best explanation ever!


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.