Search code examples
springhibernateehcachesecond-level-cache

hibernate second level cache keeps emptying itself


Have a Spring/Tomcat application and I'm trying to get ehcache working as Hibernate second-level entity cache. It is enabled and active. I can see in the debug log output how many entities are cached. The problem is that every few seconds, the cache empties. I even pinned the cache (just to see if that would alter the behavior) and now I see this:

05-08-2017 16:05:21.550 [taskExecutor-12] {env=''} WARN  n.s.e.Cache: Data availability impacted:
****************************************************************************************
************************** removeAll called on a pinned cache **************************

05-08-2017 16:05:21.550 [taskExecutor-12] {env=''} WARN  n.s.e.Cache: Data availability impacted:
****************************************************************************************
************************** removeAll called on a pinned cache **************************

So I think this is the problem. Any idea what would cause removeAll to be implicitly called over and over?

ehcache.xml

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="ehcache.xsd"
    updateCheck="true"
    monitoring="autodetect"
    maxBytesLocalHeap="24G"
    dynamicConfig="true">

    <defaultCache eternal="true" maxBytesLocalHeap="1" /> <!-- not used, but required per ehcache configuration rules -->

    <!-- cache for foo -->
    <cache name="foo"
           maxBytesLocalHeap="8G"
           eternal="false"
           memoryStoreEvictionPolicy="LRU"
           timeToLiveSeconds="12000"
           transactionalMode="off">
        <pinning store="inCache" />
        <persistence strategy="none" />
    </cache>
</ehcache>

persistence.xml

        <properties>
            <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect" />
            <property name="hibernate.connection.driver_class" value="org.postgresql.Driver" />
            <property name="hibernate.show_sql" value="false" />
            <property name="hibernate.hbm2ddl.auto" value="update" />
            <property name="hibernate.ejb.naming_strategy" value="org.hibernate.cfg.ImprovedNamingStrategy" />
            <property name="hibernate.cache.provider_class" value="org.hibernate.cache.EhCacheProvider" />
            <property name="hibernate.cache.use_second_level_cache" value="true" />
            <property name="hibernate.cache.use_query_cache" value="false" />
            <property name="hibernate.generate_statistics" value="true" />
            <property name="hibernate.cache.use_structured_entries" value="true" />
            <property name="hibernate.cache.region.factory_class" value="org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory" />
        </properties>

And these annotations are on the entity model class:

@Cacheable
@Cache(region = "foo", usage = CacheConcurrencyStrategy.READ_WRITE)

Solution

  • I figured it out. Native SQL DELETE queries were causing hibernate to frequently dump the entire cache (the removeAll calls above). I did as suggested below, and everything is working now.

    2nd level cache invalidation with native queries