2

I have a Spring Boot application using Spring Caching annotations. Now I want to migrate to JSR-107 (JCache) annotations.

This is my method:

@Cacheable(value = "results", key = "#input.id")
public CalculatorResult calculate(CalculatorInput input, Operation operation) { 
    // Code omitted for simplicity
}

And I want my new method something like this:

@CacheResult(cacheName = "results")
public CalculatorResult calculate(@CacheKey CalculatorInput input, Operation operation) {
    // Code omitted for simplicity
}

The CalculatorInput class:

public class CalculatorInput {
    private String id;
    private Double num1;
    // Getters and setters omitted for simplicity
}

The @CacheKey annotation instructs spring to store the whole CalculatorInput Object as Key. I would like using as key only the attribute id of CalculatorInput class.

How can I create a cache key (as I did with Spring caching annotation) but using JCache?

Thank you.

lauer
  • 167
  • 10

1 Answers1

3

Add the attribute cacheKeyGenerator to your @CacheResult annotation. Write a class implementing CacheKeyGenerator (example) and use it in the annotation. The generator's method generateCacheKey receives a context object which gives you access to the cached method invocation's parameter values from which you can obviously extract the desired key.

Hero Wanders
  • 3,237
  • 1
  • 10
  • 14
  • Thanks Hero Wanders. The problem with CachePut is that this annotation does not cause the advised method to be skipped. I don't want my method to be executed if the key already exists in memory. – lauer Sep 14 '18 at 23:50
  • I modified my answer. You may add that annotation attribute to @CacheResult too (and leave out the @CachePut). According to the documentation you should see the desired behavior then. – Hero Wanders Sep 15 '18 at 00:03
  • In your mentioned example, where does DefaultGeneratedCacheKey come from? DefaultGeneratedCacheKey class is not part of JCache specification, and there is not example of the implementation. – lauer Sep 15 '18 at 00:20
  • DefaultGeneratedCacheKey is part of the reference implementation: https://github.com/jsr107/RI/blob/599a9601353a68e49a748ef529577d231ddccff9/cache-annotations-ri/cache-annotations-ri-common/src/main/java/org/jsr107/ri/annotations/DefaultGeneratedCacheKey.java -- But you can easily write a class implementing `GeneratedCacheKey` by yourself! In your case that class would simply wrap a simple `String` plus implement the necessary `hashCode` and `equals` methods: https://static.javadoc.io/javax.cache/cache-api/1.0.0/javax/cache/annotation/GeneratedCacheKey.html – Hero Wanders Sep 15 '18 at 00:24
  • That is what I was needing. Very difficult to find that info. I will give it a try and tell you. Thanks. – lauer Sep 15 '18 at 00:48
  • Good to know it actually works for you. If you think this is the right answer, you may officially accept by clicking the checkmark next to it and help others to see this question has actually been answered. – Hero Wanders Sep 16 '18 at 23:21