title: How to implement CacheLoader so that @Cacheable key is read
body: <p>In attempting to implment my own cache loader using inline refresh. This cache loaded is using RefreshAheadCacheFactory</p>
  
  <p>as described at</p>
  
  <blockquote>
    <p><a href="http://terracotta.org/documentation/4.1/bigmemorymax/api/refresh-ahead#scheduled-refresh-ahead" rel="nofollow">http://terracotta.org/documentation/4.1/bigmemorymax/api/refresh-ahead#scheduled-refresh-ahead</a></p>
    
    <p>&amp;</p>
    
    <p><a href="http://www.ehcache.org/generated/2.9.0/html/ehc-all/#page/Ehcache_Documentation_Set%2Fco-dec_creating_a_decorator_2.html" rel="nofollow">http://www.ehcache.org/generated/2.9.0/html/ehc-all/#page/Ehcache_Documentation_Set%2Fco-dec_creating_a_decorator_2.html</a></p>
  </blockquote>
  
  <p>I'm receiving an error when attempt to add my own key : </p>
  
  <pre><code>@Cacheable(key="myKey" , value = "myCache")
  </code></pre>
  
  <p>error is : </p>
  
  <pre><code>org.springframework.expression.spel.SpelEvaluationException: EL1008E:(pos 0): Field or property 'myKey' cannot be found on object of type 'org.springframework.cache.interceptor.CacheExpressionRootObject'
      at org.springframework.expression.spel.ast.PropertyOrFieldReference.readProperty(PropertyOrFieldReference.java:208)
      at org.springframework.expression.spel.ast.PropertyOrFieldReference.getValueInternal(PropertyOrFieldReference.java:72)
      at org.springframework.expression.spel.ast.SpelNodeImpl.getValue(SpelNodeImpl.java:93)
      at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:88)
      at org.springframework.cache.interceptor.ExpressionEvaluator.key(ExpressionEvaluator.java:80)
      at org.springframework.cache.interceptor.CacheAspectSupport$CacheOperationContext.generateKey(CacheAspectSupport.java:464)
      at org.springframework.cache.interceptor.CacheAspectSupport.inspectCacheables(CacheAspectSupport.java:291)
      at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:198)
      at org.springframework.cache.interceptor.CacheInterceptor.invoke(CacheInterceptor.java:66)
      at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
      at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:622)
      at ehcache.MyCache$$EnhancerByCGLIB$$4aeb3b9c.tester(&lt;generated&gt;)
      at ehcache.TestEhcache.testCache(TestEhcache.java:21)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
      at java.lang.reflect.Method.invoke(Method.java:597)
      at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
      at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
      at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
      at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
      at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
      at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83)
      at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
      at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
      at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
      at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
      at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
      at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
      at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
      at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
      at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
      at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
      at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
      at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
      at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
      at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
      at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
      at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
      at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
      at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
  </code></pre>
  
  <p>How can I add the key "myKey" to the cache ?</p>
  
  <p>I think I've setup the custom cache loader incorrectly.
  How shold the loadAll method be implemented. Here is my implementation  :</p>
  
  <pre><code>public Map loadAll(Collection keys, Object argument) {
      // TODO Auto-generated method stub
  
      return new HashMap&lt;String , String&gt;();
  }
  </code></pre>
  
  <p>Should this HashMap contain the key "myKey" ?</p>
  
  <p>When I customise this method : </p>
  
  <pre><code>public Map loadAll(Collection keys, Object argument) {
  // TODO Auto-generated method stub
   Map map = new HashMap&lt;String , String&gt;();
   map.put("myKey", "test");
  
  return map;
  </code></pre>
  
  <p>}</p>
  
  <p>I receive same error.</p>
  
  <p>All code &amp; config : </p>
  
  <p>spring-ehcache.xml : </p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util"
      xmlns:cache="http://www.springframework.org/schema/cache"
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd
       http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"&gt;
      &lt;cache:annotation-driven /&gt;
      &lt;bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager"
          p:cache-manager-ref="ehcache" /&gt;
      &lt;bean id="ehcache"
          class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"
          p:config-location="my-ehcache.xml" /&gt;
  
      &lt;bean id="myCache" class="ehcache.MyCache"&gt;&lt;/bean&gt;
  &lt;/beans&gt;
  </code></pre>
  
  <p>my-ehcache.xml : </p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"&gt;
      &lt;defaultCache eternal="true" maxElementsInMemory="100"
          overflowToDisk="false" /&gt;
      &lt;cache name="myCache" maxElementsInMemory="10" eternal="true"
          overflowToDisk="false"&gt;
  
    &lt;cacheLoaderFactory class="MyCacheLoaderFactory" properties="myKey" 
      /&gt;
  
          &lt;cacheDecoratorFactory 
              class="net.sf.ehcache.constructs.refreshahead.RefreshAheadCacheFactory"
              properties="timeToRefreshSeconds=10,
        batchSize=5,
        numberOfThreads=4,
        maximumBacklogItems=5,
        evictOnLoadMiss=true" /&gt;
  
      &lt;/cache&gt;
  &lt;/ehcache&gt;
  </code></pre>
  
  <hr>
  
  <pre><code>package ehcache;
  
  import org.junit.Test;
  import org.junit.runner.RunWith;
  import org.springframework.beans.factory.annotation.Autowired;
  import org.springframework.test.context.ContextConfiguration;
  import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
  
  @RunWith(SpringJUnit4ClassRunner.class)
  @ContextConfiguration("classpath:spring-ehcache.xml")
  public class TestEhcache {
  
      @Test
      public void testCache(){
  
          while(true){
  
  
              long t1 = System.currentTimeMillis();
  
              System.out.println(myCache.tester());
              try {
                  Thread.sleep(1000);
              } catch (InterruptedException e) {
                  e.printStackTrace();
              }
  
              long t2 = System.currentTimeMillis();
  
              System.out.println("Exc time : "+(t2-t1));
          }
      }
  
  
      @Autowired
      private MyCache myCache;
  
  }
  
  
  
  package ehcache;
  
  import org.springframework.cache.annotation.Cacheable;
  
  public class MyCache {
  
      @Cacheable(key="myKey" , value = "myCache")
      public String tester() {
  
          System.out.println("in cache");
          ExpensiveOperation expensiveOperation = new ExpensiveOperation();
          String ret = expensiveOperation.doThis();
  
          return ret;
      }
  
  }
  
  package ehcache;
  
  public class ExpensiveOperation {
  
      public String doThis() {
  
          try {
              Thread.sleep(3000);
          } catch (InterruptedException e) {
              e.printStackTrace();
          }
  
          return "test";
      }
  
  }
  
  import java.util.Properties;
  import net.sf.ehcache.Ehcache;
  import net.sf.ehcache.loader.CacheLoader;
  
  public class MyCacheLoaderFactory extends
          net.sf.ehcache.loader.CacheLoaderFactory {
  
          @Override
          public CacheLoader createCacheLoader(Ehcache cache, Properties properties) {
  
              return new MyCacheLoader();
  
          }
  
      }
  
  import java.util.Collection;
  import java.util.HashMap;
  import java.util.Map;
  
  import net.sf.ehcache.CacheException;
  import net.sf.ehcache.Ehcache;
  import net.sf.ehcache.Status;
  import net.sf.ehcache.loader.CacheLoader;
  
  
  public class MyCacheLoader implements CacheLoader {
  
      public Object load(Object key) throws CacheException {
          // TODO Auto-generated method stub
          return load(key, null);
      }
  
      public Map loadAll(Collection keys) {
          // TODO Auto-generated method stub
  
          System.out.println("in loadall");
  
          return loadAll(keys , null);
      }
  
      public Object load(Object key, Object argument) {
  
          System.out.println("in load");
          // TODO Auto-generated method stub
          return "my object";
      }
  
      public Map loadAll(Collection keys, Object argument) {
          // TODO Auto-generated method stub
           Map map = new HashMap&lt;String , String&gt;();
           map.put("myKey", "test");
  
          return map;
      }
  
      public String getName() {
          // TODO Auto-generated method stub
          return null;
      }
  
      public CacheLoader clone(Ehcache cache) throws CloneNotSupportedException {
          // TODO Auto-generated method stub
          return null;
      }
  
      public void init() {
          // TODO Auto-generated method stub
  
      }
  
      public void dispose() throws CacheException {
          // TODO Auto-generated method stub
  
      }
  
      public Status getStatus() {
          // TODO Auto-generated method stub
          return null;
      }
  
  }
  </code></pre>