title: Is it possible to evict spring cache partial data?
body: <p>Given these entities and the repository to access their data in DDBB:</p>
  
  <pre><code>@Entity
  public class Customer {
  Long id;
  }
  
  @Entity
  public class Purchase {
      Long customerId;
  }
  
  @Repository
  public lass PurchaseDAO {
  
     public void insert(Purchase insert);
  
     public void deleteCustomerPurchases(Long customerId);
  
     public long getTotalPurchasesAmount(Long customerId);
  
     public long getTotalPurchasesAmountPerMonth(Long customerId, int month);
  }
  </code></pre>
  
  <p>I want to add cache for method getTotalPurchaseAmounts(Long customerId), in such way that, when adding some purchase for a customer, only purchasesd of that customer are evicted.</p>
  
  <p>The related dependance entries are:</p>
  
  <pre><code>        &lt;dependency&gt;
              &lt;groupId&gt;org.springframework&lt;/groupId&gt;
              &lt;artifactId&gt;spring-beans&lt;/artifactId&gt;
              &lt;version&gt;4.2.3.RELEASE&lt;/version&gt;
          &lt;/dependency&gt;
          &lt;dependency&gt;
              &lt;groupId&gt;org.springframework&lt;/groupId&gt;
              &lt;artifactId&gt;spring-context&lt;/artifactId&gt;
              &lt;version&gt;4.2.3.RELEASE&lt;/version&gt;
          &lt;/dependency&gt;
          &lt;dependency&gt;
              &lt;groupId&gt;org.springframework&lt;/groupId&gt;
              &lt;artifactId&gt;spring-context-support&lt;/artifactId&gt;
              &lt;version&gt;4.2.3.RELEASE&lt;/version&gt;
          &lt;/dependency&gt;
          &lt;dependency&gt;
              &lt;groupId&gt;net.sf.ehcache&lt;/groupId&gt;
              &lt;artifactId&gt;ehcache&lt;/artifactId&gt;
              &lt;version&gt;2.10.2&lt;/version&gt;
          &lt;/dependency&gt;
  </code></pre>
  
  <p>Related configuration:</p>
  
  <pre><code>@EnableCaching
  @Configuration
  public class CommonConfig {
  
      @Bean
      public CacheManager cacheManager() {
          EhCacheCacheManager cacheManager = new EhCacheCacheManager();
          cacheManager.setCacheManager( ehCacheManager().getObject() );
          return cacheManager;
      }
  
      @Bean
      public EhCacheManagerFactoryBean ehCacheManager() {
          EhCacheManagerFactoryBean ehcache = new EhCacheManagerFactoryBean();
          ehcache.setConfigLocation( new ClassPathResource( "ehcache.xml" ) );
          return ehcache;
      }
  
  }
  </code></pre>
  
  <p>As spring cache (and ehcache) evicts are limited as per element or all entries, the solution I have developed is creating caches dinamically (one for each customer) so I can evict those.</p>
  
  <p>The extension point I thinks is the best for this is implementing a custom CacheResolver:</p>
  
  <pre><code>@Component("CustomerPurchasesCacheResolver")
  public class CustomerPurchasesCacheResolver implements CacheResolver {
  
      @Autowired
      private EhCacheCacheManager cacheManager;
  
      @Override
      public Collection&lt;? extends Cache&gt; resolveCaches( CacheOperationInvocationContext&lt;?&gt; context ) {
          String cacheName = "customerPurchases_" + getCustomerId( context );
          // Add cache to cacheManager if it does not exists
          cacheManager.getCacheManager().addCacheIfAbsent( cacheName );
  
          Set&lt;Cache&gt; caches = new HashSet&lt;&gt;();
          caches.add( cacheManager.getCache( cacheName ) );
          return caches;
      }
  
      // Retrieves customerId from cache operation invocation context;
      private Long getCustomerId( CacheOperationInvocationContext&lt;?&gt; context ) {
      String key = ( (CacheOperation) context.getOperation() ).getKey();
          // TODO Evaluate key
          // HOW CAN I DO THIS????????????
          return null;
      }
  
  }
  </code></pre>
  
  <p>and adding Spring cache to my repository methods:</p>
  
  <pre><code>@Repository
  public lass PurchaseDAO {
  
     @CacheEvict(cacheResolver="CustomerPurchasesCacheResolver", key="#purchase.customerId")       
     public void insert(Purchase purchase);
  
     @CacheEvict(cacheResolver="CustomerPurchasesCacheResolver", key="#customerId")       
     public void deleteCustomerPurchases(Long customerId);
  
     @Cacheable(cacheResolver="CustomerPurchasesCacheResolver")
     public long getTotalPurchasesAmount(Long customerId);
  
     @Cacheable(cacheResolver="CustomerPurchasesCacheResolver")
     public long getTotalPurchasesAmountPerMonth(Long customerId, int month);
  
  }
  </code></pre>
  
  <p>The only problem I get using this aproach is to get the key evaluated using Spring Expresions.</p>
  
  <p>Is there any way to get that or a different aproach that could work?</p>