question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

@CacheEvict should allow multiple key values [SPR-10958]

See original GitHub issue

Ashot Golovenko opened SPR-10958 and commented

Currently you can evict only one or all elements in a single cache region. Allowing something like

@CacheEvict(value = "userCache", key = {"key1", "key2"})

would be really handful.


Affects: 3.2.4

12 votes, 14 watchers

Issue Analytics

  • State:closed
  • Created 10 years ago
  • Comments:20

github_iconTop GitHub Comments

1reaction
spring-projects-issuescommented, Jan 11, 2019

Kyle Lieber commented

We could really use this functionality as well. I think the suggestions made by @jkuhs would work. Here my scenario if it helps:

We have a Policy and a Product.

I have a Policy which is identified by a policyId and each Policy can have multiple Products which are identified by the policyId and the productCode.

So I have a ProductService with a method for getting a product by policyId and productCode.

public class ProductService {
  @Cacheable("products")
  public Product getProduct(Integer policyId, String productCode) {  }
}

Then I have a PolicyService which has a method for deleting a Policy when given the policyId.

public class PolicyService {
  public void deletePolicy(Integer policyId) {  }
}

The PolicyService#deletePolicy will also delete all products for that policy but I have no way to clear the products cache for that policy.

My workaround options are:

  1. Clear all entries in the cache. This is really not an option because this will affect all products for all policies.
  2. Do something really ugly like this:
public class ProductService {
  @Cacheable("products")
  public Product getProduct(Integer policyId, String productCode) {  }

  public List<Product> getAllProducts(Integer policyId) { }

  @CacheEvict("products")
  public void evictFromCache(Integer policyId, String productCode) {
    // this method doesn't do anything and is only here for evicting the cache
  }
}
public class PolicyService {
  public void deletePolicy(Integer policyId) {
    // first delete the policy
    doDelete(policyId);
    // then evict the products
    for (Product product : productService.getAllProducts(policyId)) {
      productService.evictFromCache(policyId, product.code);
    }
  }
}
1reaction
spring-projects-issuescommented, Jan 11, 2019

Johannes Kuhs commented

For more advanced caching scenarios, some concept of having multiple keys is definitely necessary in my opinion. I’m not sure it needs to be in the form of allowing multiple key values though. The key is used for retrieving a cache entry but really we just need a way to evict specific entries. So instead, it might make more sense to add a new evictKeys parameter. evictKeys simply point to the key and can thus be used to evict the actual entry.

Another use-case for this kind of functionality would be the caching of different product information. A product might have skus, images, prices, features, facets, and other information attached to it that require more expensive operations (e.g. looping through all images to find a certain image type + view, getting a specific customer price, creating a distinct set of facets across skus, etc.). It would be nice to be able to cache the results of these kind of operations and simply evict them based on the product ID when the product is updated.

Updating the existing annotations to support this could look like this:

@Cacheable(value = "productImages", key = "#product.id + #imageType", evictKeys = { "#product.id" })
public Image getProductImageOfType(Product product, String imageType)

@CacheEvict(value = "productImages", evictKeys = { "product.id" })
public void updateProduct(Product product)
Read more comments on GitHub >

github_iconTop Results From Across the Web

Cache evict on one of multiple keys - java - Stack Overflow
In general a cache acts like a hash table, you can only operate on a unique key. Selecting everything which belongs to a...
Read more >
Cache Eviction in Spring Boot - Baeldung
Here's how we can implement these two cache eviction mechanisms in code. ... @CacheEvict(value = "first", key = "#cacheKey") public void ...
Read more >
29. Cache Abstraction - Spring
For caching declaration, the abstraction provides two Java annotations: @Cacheable and @CacheEvict which allow methods to trigger cache population or cache ...
Read more >
Spring Boot Caffeine 기본 세팅
value = cache 저장소, key = 저장소 key값 @Cacheable(value ... @CacheEvict should allow multiple key values [SPR-10958] · Issue #15586 ...
Read more >
Spring Cache Evict - LogicBig
By default, @CacheEvict will cause the target cache to be removed after ... This allows new value to be cached via @Cacheable after...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found