Hibernate Books

All times are UTC - 5 hours [ DST ]



Post new topic Reply to topic  [ 4 posts ] 
Author Message
 Post subject: QueryCache is not working when record is not available in DB
PostPosted: Thu Jan 12, 2017 5:54 am 
Newbie

Joined: Thu Jan 12, 2017 5:44 am
Posts: 2
Code:
@Entity
@Table
@Cache(usage = CacheConcurrencyStrategy.READ_ONLY, region = "Account_region")
public class Account
{
    @Id
    private int accId;

    @Column
    private String name;

}


hibernate-cfg.xml

Code:
<property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
      <property name="hibernate.cache.use_second_level_cache">true</property>
      <property name="hibernate.cache.use_query_cache">true</property>
      <property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>

      <!-- optional -->
      <property name="hibernate.generate_statistics">true</property>


Code:
Test.java
{
private static void printStats(Statistics stats, int i)
    {
        logger.info("***** " + i + " *****");
        logger.info("Fetch Count=" + stats.getEntityFetchCount());
        logger.info("Second Level Hit Count=" + stats.getSecondLevelCacheHitCount());
        logger.info("Second Level Miss Count=" + stats.getSecondLevelCacheMissCount());
        logger.info("Second Level Put Count=" + stats.getSecondLevelCachePutCount());
    }
private void createAccount(int id)
    {
        Account acc = new Account();
        acc.setAccId(id);
        acc.setName("Finance");
        session.save(acc);
        logger.info("Account succesfully created.");
    }
private void fetchAccount(int id)
    {
        try
        {
            logger.info("Before fetching acc with id : {}", id);
            printStats(stats, i++);
            Criteria criteria = session.createCriteria(Account.class);
            criteria.add(Restrictions.idEq(id));
            criteria.setCacheable(true);
            System.out.println(criteria.list());
            logger.info("After fetching acc with id : {}", id);
            printStats(stats, i++);
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }
@Test
    public void test1()
    {
        logger.info("Initial statistics.");
        printStats(stats, i++);
        int id = 1;
        createAccount(id);
        fetchAccount(id);
        [color=#FF0000]fetchAccount(id);[/color]
    }
}


When the marked line is executing, why it is firing the query again though that query has already been cached?


Top
 Profile  
 
 Post subject: Re: QueryCache is not working when record is not available in DB
PostPosted: Thu Jan 12, 2017 7:44 am 
Hibernate Team
Hibernate Team

Joined: Thu Sep 11, 2014 2:50 am
Posts: 1038
1. I noticed that you are using an old configuration:

Code:
hibernate.cache.provider_class


Try removing it since you already have this configuration in place:

Code:
<property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>


2. You are also not using transactions. Please use transactions even for read-only queries, as explained in this StackOverflow question.

Now back to your problem, I tried to replicate your issue but it works just fine for me.
You can fork this test from [url=https://github.com/vladmihalcea/high-performance-java-persistence/blob/master/core/src/test/java/com/vladmihalcea/book/hpjp/hibernate/cache/QueryCacheTest.java#L101my GitHub repository[/url] to see that the Query Cache works just fine with empty result sets as well.

_________________
If you liked my answer, you are going to love my High-Performance Java Persistence book and my blog as well.


Top
 Profile  
 
 Post subject: Re: QueryCache is not working when record is not available in DB
PostPosted: Fri Jan 13, 2017 3:09 am 
Newbie

Joined: Thu Jan 12, 2017 5:44 am
Posts: 2
Thanks Vlad for reply.
#1. I removed the hibernate.cache.provider_class from config file but issue still exist.
#2. I start the transaction @Before and commit it on @After. So basically for every @Test, transaction has already started.

One thing I have noticed here, If we are inserting and fetching a record in same session then this issue comes.
1. Open session and begin transaction.
2. Insert a record into DB
3. Fetch the same record from DB.
4. Fetch the same record from DB.

In #4 I am not expecting hibernate fire the query. It should be taken from cache.

If we inserting and fetching is done in different session, then there is no issue.
1. Open session and begin transaction.
2. Insert a record into DB
3. Commit the transaction and close the session.
4. Open another session and begin transaction.
5. Fetch the same record from DB.
6. Fetch the same record from DB.

Hibernate doesn't fire any query on #6.
Could someone please explain these.

Another point is, if you enable hibernate cache logs, then hibernate invalidating the cache after insertion. I don't why?


Top
 Profile  
 
 Post subject: Re: QueryCache is not working when record is not available in DB
PostPosted: Sat Jan 14, 2017 3:36 am 
Hibernate Team
Hibernate Team

Joined: Thu Sep 11, 2014 2:50 am
Posts: 1038
That's the expected behavior. Every modification t the table space invalidates the query cache. Check out this article (How does Hibernate Query Cache work) for more details.

_________________
If you liked my answer, you are going to love my High-Performance Java Persistence book and my blog as well.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 4 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:
cron
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.