ehcache-3

EhCache 3, how to use Objects as keys


When I read the cache it never finds the cached values, it always says "CacheInterceptor - No cache entry for key" and recreates a key/value pair in the cache. It doesn't matter what combination of parameters I use, it never finds anything in the cache that matches. What am I missing?

I have:

The configuration class (it reads in the .xml file ehcache.xml)

@Configuration
@EnableCaching
public class CacheConfig {

@Autowired
private javax.cache.CacheManager cacheManager;

}

application.yml

spring:
  cache:
    jcache:
      config: classpath:ehcache.xml

ehcache.xml (in src/main/resources)

...
<cache alias="cmsLabelsCache">
    <expiry>
        <ttl unit="seconds">10</ttl>
    </expiry>
    <heap unit="entries">10000</heap>
</cache>
....

The Service with a @Cacheable method

@Service
public class CMSPropertiesService {

@Cacheable(value = "cmsLabelsCache", key = "{#cmsSpecificRequest, #langAndMarket, #labelKey}")
public String getLabelWithReferences(@NotNull String cmsSpecificRequest, @NotNull LangAndMarket langAndMarket, @NotNull String labelKey) {
    String label = "[" + cmsSpecificRequest 
                 + ", " + langAndMarket.toString() + ", " + labelKey + "]";
    return label;
}

the LangAndMarket class

    public static class LangAndMarket {

    private String lang;
    private String market;

    ... getters, setters, constructors. lang and market @NotNull

Solution

  • The Object used as a key, LangAndMarket, must override hashCode() and equals(Object _obj)

    Add this to LangAndMarket:

        @Override
        public int hashCode()  {
            return (lang+market).hashCode();  // cheezy example
        }
    
        @Override
        public boolean equals(Object _other) {
            ... // the usual way of doing equals()
        }
    

    Then the key generation works. try removing hashCode() or equals() to make it stop working correctly.

    Apparently previous versions of EhCache didn't use hashCode() when calculating the keys.