简体   繁体   中英

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.

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM