6

I'm working on a Spring Boot app where I need to use both distributed (e.g. Hazelcast) and local (e.g. Guava) caches. Is there a way to configure Spring Cache to use both when using @Cacheable and decide which implementation is needed based on the cache name?

I tried with creating a configuration for both HZ and Guava defining the cache names inside, but Spring complains that it couldn't find the cache name that is supposed to handled by HZ. When I use exclusively HZ or Guava they work.

2

3 Answers 3

13

Which implementation is needed based on the cache name?

Not based on the cache name, but yes - based on the CacheManager it is possible. Declare one of them as @Primary CacheManager, as follows:

@Configuration
@EnableCaching
@PropertySource(value = { "classpath:/cache.properties" })
public class CacheConfig {

    @Bean
    @Primary
    public CacheManager hazelcastCacheManager() {
        ClientConfig config = new ClientConfig();
        HazelcastInstance client = HazelcastClient.newHazelcastClient(config);
        return new HazelcastCacheManager(client);
    }

    @Bean
    public CacheManager guavaCacheManager() {
         GuavaCacheManager cacheManager = new GuavaCacheManager("mycache");
           CacheBuilder<Object, Object> cacheBuilder = CacheBuilder.newBuilder()
           .maximumSize(100)
           .expireAfterWrite(10, TimeUnit.MINUTES);
           cacheManager.setCacheBuilder(cacheBuilder);
           return cacheManager;
    }

}

and specify it at class level as:

@Service
@CacheConfig(cacheManager="hazelcastCacheManager")
public class EmployeeServiceImpl implements IEmployeeService {

}

or at method level as:

@Service
public class EmployeeServiceImpl implements IEmployeeService {

    @Override
    @Cacheable(value = "EMPLOYEE_", key = "#id", cacheManager= "guavaCacheManager")
    public Employee getEmployee(int id) {
        return new Employee(id, "A");
    }

}

If you have to stick with Cache name only, then you can multiple CacheManager.

Sign up to request clarification or add additional context in comments.

5 Comments

I followed your solution but got this exception on startup: java.lang.IllegalStateException: No CacheResolver specified, and no unique bean of type CacheManager found. Mark one as primary (or give it the name 'cacheManager') or declare a specific CacheManager to use, that serves as the default one. I tried to use the name the error message mentions but it didn't help. Any idea on that?
Thanks for the help, it works perfectly! It's a shame that Spring doesn't cover this part properly in their docs as it's fairly simple once you get some guidelines.
@Arpit , @Balazs can we use both these cache managers in one method @Cachable ?
@SoumitriPattnaik no, only one at a time, as cacheManager is a String instance in @Cachable and not Array.
As hazelcastCacheManager is annotated with @Primary so no need to specify cacheManager= "hazelcastCacheManager" specifically.
2

You have 2 options.

One is as @Arpit mentioned: Define multiple CacheManagers and specify it in either method-level annotations (@Cacheable, @CachePut, etc) or class-level annotations (@CacheConfig)

You can also create custom annotations:

@CacheConfig(cacheManager = "guavaCacheManager")
@Target(value = ElementType.TYPE)
@Retention(value = RetentionPolicy.RUNTIME)
public @interface GuavaCacheable {
}

@GuavaCacheable
@Service
public class MyServiceImpl implements MyService {
}

And as the second option, you can create a custom cache resolver if your caching needs are complex.

You can look here for a custom CacheResolver that manages multiple CacheManagers and supports enabling/disabling. But for most cases, CacheResolver is overkill.

1 Comment

hello, I used this way. But still, Spring cannot identify which cache manager to autowire into my service class. any help please?
0

One can consider using

https://github.com/yatharthamishra0419/multimodule-cache

library for support of multiple caching system, this library is extensible,multi-module aware and support for various caching systems can be added in the framework.This also includes a annotation through which multiple sources can be used

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.