0

I am having an issue configuring a Cache in Spring boot. It was working fine and after some unrelated changes, it stopped working.

I have the following cache configuration:

@Configuration
public class UserMappingCacheConfig {
    public static final String USER_MAPPING_CACHE = "userMappingCache";

@Bean(name = "userMappingCache")
public Cache<String, String> getUserMappingCache(JCacheCacheManager cacheManager) {
    CacheManager cm = cacheManager.getCacheManager();
    Cache<String, String> cache = cm.getCache(USER_MAPPING_CACHE, String.class, String.class);
    if (cache == null)
        cache = cm.createCache(USER_MAPPING_CACHE, getUserMappingCacheConfiguration());
    return cache;
}

private MutableConfiguration<String, String> getUserMappingCacheConfiguration() {
    MutableConfiguration<String, String> configuration =
            new MutableConfiguration<String, String>()
                    .setStoreByValue(true)
                    .setExpiryPolicyFactory( FactoryBuilder.factoryOf(
                            new CreatedExpiryPolicy( Duration.ONE_DAY)
                    ));
    return configuration;
}

And I use the cache in the following way:

@CacheResult(cacheName = "userMappingCache")
public String getPayrollUserName(@CacheKey String userName, String description) {...}

However, I get the following exception when running the service:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userMappingCache' defined in class path resource [UserMappingCacheConfig.class]: 
Bean instantiation via factory method failed;
nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.cache.Cache]: Factory method 'getUserMappingCache' threw exception; 
nested exception is java.lang.ClassCastException: Incompatible cache key types specified, expected class java.lang.Object but class java.lang.String was specified
                at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:599) ~[spring-beans-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    ....
    Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.cache.Cache]: Factory method 'getUserMappingCache' threw exception; 
nested exception is java.lang.ClassCastException: Incompatible cache key types specified, expected class java.lang.Object but class java.lang.String was specified
                    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:189) ~[spring-beans-4.3.11.RELEASE.jar:4.3.11.RELEASE]
                    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:588) ~[spring-beans-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    ....
    Caused by: java.lang.ClassCastException: Incompatible cache key types specified, expected class java.lang.Object but class java.lang.String was specified
                    at com.hazelcast.cache.impl.AbstractHazelcastCacheManager.getCache(AbstractHazelcastCacheManager.java:200) ~[hazelcast-3.10.jar:3.10]
                    at com.hazelcast.cache.impl.AbstractHazelcastCacheManager.getCache(AbstractHazelcastCacheManager.java:67) ~[hazelcast-3.10.jar:3.10]

I googled around, and found some entries which mostly relate similar issues to serialization of the keys/values. Is that the reason even with a primitive class? How can I fix it? Thanks in advance.

JPS
  • 526
  • 7
  • 19
  • 1
    What versions of Spring Boot, Hazelcast and JCache are you using and were you using before ? JCache changed from 1.0 to 1.1 recently, might be that if it's a dependency change. Also, your `MutableConfiguration` doesn't do `setType(Class,Class)` whereas the `@CacheKey`/`@CacheResult` pairing imply _String_. – Neil Stevenson Aug 30 '18 at 10:45
  • @NeilStevenson, you nailed it with the setTypes(Class,Class). Hadn't come across it in the examples and docs. Thanks! – JPS Aug 30 '18 at 12:54
  • Btw, if you post your comment as an answer, I'll accept it. – JPS Aug 30 '18 at 13:00
  • Have done, happy to help – Neil Stevenson Aug 30 '18 at 20:00

1 Answers1

2

From my comment, seems the answer is that MutableConfiguration is not using

setType(Class<K>,Class<V>)

which would configure the key and value type of the cache. Without which it will default to Object, and this is incompatible with the (implied) type of String that the @CacheKey/@CacheResult pairing dictate.

Neil Stevenson
  • 3,060
  • 9
  • 11