@Cacheble annotation on no parameter method

41.4k Views Asked by At

I want to have @Cacheable annotation on method with no parameter. In that case, I use @Cacheable as follows

@Cacheable(value="usercache", key = "mykey")
public string sayHello(){
    return "test"
}

However, when I call this method, it doesn't get executed and it get exception as below

org.springframework.expression.spel.SpelEvaluationException: EL1008E:(pos 0): Property or field 'mykey' cannot be found on object of type 'org.springframework.cache.interceptor.CacheExpressionRootObject' - maybe not public?

Please suggest.

6

There are 6 best solutions below

5
Ruben On BEST ANSWER

It seems that Spring doesn't allow you to provide a static text for the cache key in the SPEL, and it doesn't include as default the name of the method on the key, so, you could be in a situation when two methods using the same cacheName and without a key would potentially cache different results with the same key.

The easiest workaround is to provide the name of the method as the key:

@Cacheable(value="usercache", key = "#root.methodName")
public string sayHello(){
return "test"
}

This would set sayHello as the key.

If you really need a static key, you should define a static variable in the class, and use #root.target:

public static final String MY_KEY = "mykey";

@Cacheable(value="usercache", key = "#root.target.MY_KEY")
public string sayHello(){
return "test"
}

You can find here the list of SPEL expressions that you can use in your key.

2
Cliff On

Try adding single quotes around mykey. It's a SPEL expression, and the singles quotes make it a String again.

@Cacheable(value="usercache", key = "'mykey'")
1
Giggs On

Add # in the key

@Cacheable(value="usercache", key = "#mykey")
public string sayHello(){
    return "test"
}
4
Terran On

You can omit the key parameter. Spring will then put the value with key SimpleKey.EMPTY into the cache:

@Cacheable("usercache")

Alternatively (apart from using SPEL outlined in the other solutions) you can always inject the CacheManager and manually handle it.

0
vuhoanghiep1993 On

For me problem is the syntax of key is not right

@Cacheable(value = "name", key = "#object.field1+object.field2")

Right is need # before key items:

@Cacheable(value = "name", key = "#object.field1+#object.field2")
0
Vishal Bramhankar On

I missed to add # before id, like key must be look like, key="#id" not key="id"

@GetMapping("/{id}")
@Cacheable(key = "#id", value = "book")
public Book getBookById(@PathVariable Long id) {
    return bookService.getBookById(id);
}