0

We want to take advantage of the ehcache library used in the dxa project for our custom methods other than the existing dd4t object caching. I modified the configuration as per Spring Caching Example + EhCache. However my custom method gets executed on every refresh and does not return the cached object as the example stated. I can see the following logs in the ehcache-logfile.


CacheManager - CacheManager already shutdown ConfigurationFactory - Configuring ehcache from ehcache.xml found in the classpath: file:/D:/apache/tomcat-sh-staging-web1/webapps/ROOT/WEB-INF/classes/ehcache.xml MemoryStore - Initialized net.sf.ehcache.store.MemoryStore for customBrandListCache ExtendedStatisticsImpl - Mocking Pass-Through Statistic: LOCAL_OFFHEAP_SIZE ExtendedStatisticsImpl - Mocking Pass-Through Statistic: LOCAL_OFFHEAP_SIZE_BYTES Cache - Initialised cache: customBrandListCache ConfigurationHelper - CacheDecoratorFactory not configured. Skipping for 'customBrandListCache'. ConfigurationHelper - CacheDecoratorFactory not configured for defaultCache. Skipping for 'customBrandListCache'. CacheManager - Attempting to create an existing singleton. Existing singleton returned.


ehcache.xml

<cache name="DD4T-Objects"
       eternal="false"
       maxEntriesLocalHeap="10000"
       timeToLiveSeconds="3600"
       timeToIdleSeconds="60"
       memoryStoreEvictionPolicy="LRU">
</cache>
<cache name="DD4T-Dependencies"
       maxEntriesLocalHeap="50000"
       memoryStoreEvictionPolicy="LRU">
</cache>
<cache name="customBrandListCache" 
    maxEntriesLocalHeap="10000"
    eternal="false" 
    timeToIdleSeconds="0" timeToLiveSeconds="600"
    memoryStoreEvictionPolicy="LRU" 
    transactionalMode="off">
    <!--<persistence strategy="none" />-->
</cache>

spring-context.xml

<context:annotation-config/>
<context:component-scan base-package="com.sdl.webapp, com.sdl.dxa, com.khayal.shero"/>


<!-- DD4T Cache Provider -->
<bean id="cacheProvider" class="org.dd4t.core.providers.EHCacheProvider">
    <property name="checkForPreview" value="true"/>
</bean>

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

<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager" p:cacheManager-ref="ehcache"/>
<!-- Uncomment this if you want to disable the cache in DD4T -->
<!-- bean id="cacheProvider" class="org.dd4t.providers.impl.NoCacheProvider"/ -->

<!-- Enables caching through annotations -->

<cache:annotation-driven key-generator="enhancedDefaultKeyGenerator"/>
<bean id ="enhancedDefaultKeyGenerator" class="com.sdl.dxa.EnhancedDefaultKeyGenerator"/>

Method

@Cacheable(value="customBrandListCache", key="#entityId")
public BrandList getCachedCustomBrandList(Entity objEntity, int entityId, String brandListType, CommonRequestServices commonRequestServices,  String searchText) {
    long startTime = System.currentTimeMillis(), endTime;
    LOG.error(" Entered getCachedCustomBrandList "); 
    //String methodParams = "[Entity Id: " + objEntity.getId() + "
   ...
   return objBrandList;
 }

Calling class

CacheMethods cacheMethod = new CacheMethods(request);
entity = (Entity) cacheMethod.getCachedCustomBrandList(entity,Integer.parseInt(entity.getId()), BrandSearchService.BRANDLISTTYPE_TOP_BRANDS, commonRequestServices, "");

But the logs show that the code is implemented everytime. Can anyone help me? Is something wrong with the configuration? I am not getting any more logs than the one listed above. Nothing gets generated on refreshing the page.

  • Some points I got from searching a bit. @EnableCaching annotation on your context configuration class. I have done this. Providing appropriate cache manager beans --Done. Separating service bean into interface and implementation. I tried this but got "nested exception is java.lang.IncompatibleClassChangeError: Implementing class". Making cached object class Serializable -- Done.Am I missing something. Please help. – Rache Jun 12 at 10:48
3

After doing a lot of trial and error, I was finally able to cache my object. Here are my findings for anyone trying to implement caching in DXA. These are not specific to DXA but common for Springs+EHCache.

  1. @EnableCaching annotation on your context configuration class,
  2. provide appropriate cache manager beans,
  3. separate service bean into interface and implementation
  4. Make cached object class Serializable.
  5. Cached key should be primitive else handle with Custom Key Generator.

For me, I had to work on step 3 and 5. That got it working. Happy coding!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.