0

I’m using Hibernate 4.3.11.Final with ehcache and Spring 3.2.11.RELEASE. I have the below Spring/ehcache configuration …

<cache:annotation-driven key-generator="cacheKeyGenerator" />

<bean id="cacheKeyGenerator" class="org.mainco.subco.myproject.util.CacheKeyGenerator" />

<bean id="cacheManager"
    class="org.springframework.cache.ehcache.EhCacheCacheManager"
    p:cacheManager-ref="ehcache"/>

<bean id="ehcache" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"
    p:configLocation="classpath:ehcache.xml"
    p:shared="true" />

<util:map id="jpaPropertyMap">
    <entry key="hibernate.show_sql" value="true" />
    <entry key="hibernate.dialect" value="org.mainco.subco.myproject.jpa.subcoMysql5Dialect" />
    <entry key="hibernate.cache.region.factory_class" value="org.hibernate.cache.ehcache.EhCacheRegionFactory" />
    <entry key="hibernate.cache.provider_class" value="org.hibernate.cache.EhCacheProvider" />
    <entry key="hibernate.cache.use_second_level_cache" value="true" />
    <entry key="hibernate.cache.use_query_cache" value="false" />
    <entry key="hibernate.generate_statistics" value="true" />
    <entry key="javax.persistence.sharedCache.mode" value="ENABLE_SELECTIVE" />
</util:map>

<bean id="sharedEntityManager"
    class="org.springframework.orm.jpa.support.SharedEntityManagerBean">
    <property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>

using the below custom key generator …

public class CacheKeyGenerator implements KeyGenerator 
{

    @Override
    public Object generate(final Object target, final Method method, 
      final Object... params) {

        final List<Object> key = new ArrayList<Object>();
        key.add(method.getDeclaringClass().getName());
        key.add(method.getName());

        for (final Object o : params) {
            key.add(o);
        }
        return key;
    } 
}

As you can see, the keys are generated based on the class name, the method name, and then any parameters. My question is, if I want to remove from my second-level cache all entries whose cache key’s first entry (because my key is an array) is “org.mainco.subco.standards.repo.StandardsDao”, how would I write such a @CacheEvict rule? The below does not work …

@Caching(evict = { @CacheEvict(value="main", key="{'org.mainco.subco.standards.repo.StandardsDao'}")})
public int deleteCorrelationTypeContexts(String categoryId)

Any guidance is appreciated. One constraint, it is not an option to use multiple second-level caches — I can only use one for this application (the one named “main”).

Dave
  • 15,639
  • 133
  • 442
  • 830

2 Answers2

0

The short answer is that this does not work. That is not the way the @CacheEvict annotation works.

And also most cache implementations do not even have such an API natively.

Louis Jacomet
  • 13,661
  • 2
  • 34
  • 43
0

I had the very same problem and also found out that "This is not the way common cache implementations work".

So you need to implement your own Cache Provider and override whatever "key's matcher" there is in the implementation of your choice.

A good answer with GuavaCache examples can be found here.

Community
  • 1
  • 1
Reginaldo Santos
  • 840
  • 11
  • 24