Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ehcache automatic key generation and @Cacheable spring annotation

Does anybody know how the default key generation for Ehcache works? If I have the following method:

@Cacheable(cacheName = CACHE_KEY) // CACHE_KEY is static final field.
public List<DataObject> list(
    int firstRecord, int maxRecords, int pageSize, FilterObject filter) {
    ....
}

where FilterObject is a custom POJO, what should I expect to be the actual cache key?

What I am observing is when using different FilterObject instances and not changing the other arguments of my method call, it always produces the same result - the first call's result is cached and returned.

Probably it is the FilterObject POJO which causes the behaviour - I suppose it is either some serialization, or .toString() issue, because I haven't overridden the relevant methods.

Still I was unable to find exact information on how the cache key for such method is being formed both in Ehcache's website and in the @Cacheable annotation documentation. I'd appreciate any information and recommendations on this topic.

like image 497
Ivaylo Slavov Avatar asked Mar 15 '12 11:03

Ivaylo Slavov


People also ask

What is difference between Ehcache and Redis cache?

You can think Redis as a shared data structure, while Ehcache is a memory block storing serialized data objects. This is the main difference. Redis as a shared data structure means you can put some predefined data structure (such as String, List, Set etc) in one language and retrieve it in another language.

What is Ehcache in spring?

EhCache is a widely used, pure Java cache that can be easily integrated with most popular Java frameworks, such as Spring and Hibernate. It is often considered to be the most convenient choice for Java applications since it can be integrated into projects easily.

What is @cacheable in spring boot?

@CacheableThis method-level annotation lets Spring Boot know that the return value of the annotated method can be cached. Each time a method marked with this @Cacheable is called, the caching behavior will be applied.

How Ehcache works in spring boot?

EhCaching Storage Tiers are as follows: On-Heap Store: Java heap memory is used to store cache entries. Off-Heap Store: It stores cache entries into primary memory (RAM). Disk Store: It uses a disk to store cache entries. Clustered Store: Remote server is used to store cache entries.


2 Answers

This is the default key generator

public class DefaultKeyGenerator implements KeyGenerator {

public static final int NO_PARAM_KEY = 0;
public static final int NULL_PARAM_KEY = 53;

public Object generate(Object target, Method method, Object... params) {
    if (params.length == 1) {
        return (params[0] == null ? NULL_PARAM_KEY : params[0]);
    }
    if (params.length == 0) {
        return NO_PARAM_KEY;
    }
    int hashCode = 17;
    for (Object object : params) {
        hashCode = 31 * hashCode + (object == null ? NULL_PARAM_KEY : object.hashCode());
    }
    return Integer.valueOf(hashCode);
}

}

As you can see, it combines the hash-codes of each method parameter.

like image 149
pap Avatar answered Nov 09 '22 22:11

pap


Everything is explained in Spring reference documentation, namely in:

28.3.1.1 Default Key Generation:

[...]

  • If more the one param is given, return a key computed from the hashes of all parameters.

To provide a different default key generator, one needs to implement the org.springframework.cache.KeyGenerator interface. Once configured, the generator will be used for each declaration that doesn not specify its own key generation strategy (see below).

and below:

28.3.1.2 Custom Key Generation Declaration:

[...] the @Cacheable annotation allows the user to specify how the key is generated through its key attribute. The developer can use SpEL to pick the arguments of interest[...]

And an example from the docs:

@Cacheable(value="books", key="#isbn.rawNumber")
public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)

So in your case you should simply implement equals() and hashCode() for FilterObject. Decent IDE can generate them for you.

like image 34
Tomasz Nurkiewicz Avatar answered Nov 10 '22 00:11

Tomasz Nurkiewicz