Search code examples
hibernatecachingspring-mvcehcache

EHCache + hibernate: multiple queries to database


I configured my app to use query caching.

Hibernate config:

hibernate.cache.region.factory_class=net.sf.ehcache.hibernate.SingletonEhCacheRegionFactory
hibernate.cache.use_query_cache=true

EHCache config:

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="false" monitoring="autodetect" dynamicConfig="false">
    <defaultCache
        maxEntriesLocalHeap="10000"
        eternal="false"
        timeToIdleSeconds="120"
        timeToLiveSeconds="120"
        maxEntriesLocalDisk="10000000"
        diskExpiryThreadIntervalSeconds="120"
        memoryStoreEvictionPolicy="LRU">
        <persistence strategy="localTempSwap"/>
    </defaultCache>
    <cache name="query.Dictionary.CountriesList"
        maxEntriesLocalHeap="10000" 
        maxEntriesLocalDisk="1000"
        eternal="false"
        timeToLiveSeconds="86400">
        <persistence strategy="localTempSwap" />
    </cache>
</ehcache>

DAO:

Criteria query = session.createCriteria(DictionaryCountry.class)
                .setCacheable(true)
                .setCacheRegion("query.Dictionary.CountriesList")
                .addOrder(Order.asc("name"));

Now when I try to populate a list of countries for the first time - the standard query is made (select * from ... where ... ). But when I do it for the second time - instead of getting from the cache the app executes a lot of get by id sql queries (select * from ... where id = ? ) ...

Is it normal behaviour?

Thank you


Solution

  • After a long time but today i had your same problem, here is an answer if someone needs help with ehcache+spring+hibernate

    the previous configuration is correct, i only would add the next:

    1.- Add: <property name="hibernate.cache.use_second_level_cache">true</property>

    2.- Set in your models

    @Cache(usage = CacheConcurrencyStrategy.READ_WRITE )

    3.- Add something like this to make your model cacheable

    <cache name="com.yourcompany.yourproyect.model.DictionaryCountry
        maxEntriesLocalHeap="10000" 
        maxEntriesLocalDisk="1000"
        eternal="false"
        timeToLiveSeconds="86400">
        <persistence strategy="localTempSwap" />
    </cache>
    

    query.setCacheable(true); Required makes your models cacheable query.setCacheRegion("query.Dictionary.CountriesList"); optional as makes cacheable at query level

    ehcache version:

    <dependency>
      <groupId>net.sf.ehcache</groupId>
      <artifactId>ehcache-core</artifactId>
      <version>2.4.5</version>
    </dependency>
    

    I think that's it as this is working for me.