Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring multi cache in one Service bean

I am using spring-4.3.

@Cacheable("productCategories")
@Override
public ProductCategory get(Object id) throws BeanNotFoundException {
    return super.get(id);
}

@Cacheable("productCategoryChildren")
public List<ProductCategory> getChildren(String parentId) {
    return productCategoryDao.getChildren(parentId);
}

First i invoke get("100") and return a entity, and then invoke getChildren("100"), i get a error java.lang.ClassCastException: com.jxs.ms.entity.ProductCategory cannot be cast to java.util.List. Is this two method use the same cache to store value?

like image 601
user1434702 Avatar asked Dec 19 '25 05:12

user1434702


1 Answers

I had a similar issue, but in my case we were using spring with memcached. Our problem was that the CacheConfiguration defaults the useNameAsKeyPrefix property to false.

The key to understand is that the underlying cache for both named caches uses the same map. In this case id and parentId can end up being the same cache key. Even though the caches are named differently in the spring cache abstraction, the underlying cache manager stores them all in the same place. So the first request to get("1234") populates the cache with a ProductCategory for the given id, "1234". Then when getChildren("1234") is called, the cache manager does a lookup ignoring the cache name and just looking for key, "1234", which it finds and returns a ProductCategory. Because the spring proxy bean is expecting a List<ProductCategory>, you end up with a ClassCastException.

Updating the config like this, fixed my problem,:

<bean id="defaultMemCacheConfiguration" class="com.google.code.ssm.providers.CacheConfiguration">
    ...
    <property name="useNameAsKeyPrefix" value="true"/>
</bean>
like image 185
Jason Buchanan Avatar answered Dec 20 '25 21:12

Jason Buchanan



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!