Search code examples
spring-bootcachinghazelcast

How to configure multiple cache in spring boot using hazelcast?


I am new to Hazelcast. I am trying to implement caching in my spring boot application. I have created a config class for hazlecast with two map configs(CacheObject and CacheList). I have two methods objectMethod() which returns a single employee Object and listMethod() which returns list of employee Objects.

I am using @cacheable annotation on objectMethod and listMethod. The problem is only the object cache is working the list cache is not working. When I run the program in debug mode the object cache is returns value without going into the method but list cache always executes the methods and gets the value from the database.

Am I missing any configuration or anything else?

I am using Spring boot version 2.1.3.RELEASE, Hazelcast version 3.11.1 and Hazelcast-spring version 3.11.1.

I tried spring actuator cache url to see the cache but I am only seeing CacheObject not CacheList.

http://localhost:8080/actuator/caches

{"cacheManagers":{"cacheManager":{"caches":{"CacheObject":{"target":"com.hazelcast.map.impl.proxy.MapProxyImpl"}}}}}

config class

@Configuration
public class HazelcastCacheConfig {

    @Bean
    public Config cacheConfig() {
        return new Config().setInstanceName("hazelcast-instance")
                .addMapConfig(new MapConfig().setName("CacheObject")
                        .setMaxSizeConfig(new MaxSizeConfig(100, MaxSizeConfig.MaxSizePolicy.FREE_HEAP_SIZE))
                        .setEvictionPolicy(EvictionPolicy.LRU).setTimeToLiveSeconds(86400))
                .addMapConfig(new MapConfig().setName("CacheList")
                        .setMaxSizeConfig(new MaxSizeConfig(100, MaxSizeConfig.MaxSizePolicy.FREE_HEAP_SIZE))
                        .setEvictionPolicy(EvictionPolicy.LRU).setTimeToLiveSeconds(86400));
    }

@cacheable annotation

@Cacheable(value="CacheList")
    public List<Employee> getEmployeeList(String a, String b, String b){
        //Query
        return employeeList;

    }
@Cacheable(value="CacheObject")
    public Employee getEmployeeObject(String a, String b, String v) {

        //Query
         return employeeObject;
    }

Employee class

public class Employee implements Serializable{

   private static final long serialVersionUID = 1L;
   private string a,
   private string b,
   private string c,
   private UUID d,
   private Map<String,String> e;
}

Solution

  • Are you using both caches in the same way? Cachable won't work if you are not working with proxy objects (don't use dependency injection).

    Also, how did you configure your cache managers?

    package test;
    
    import static org.junit.Assert.assertEquals;
    
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.cache.CacheManager;
    import org.springframework.cache.annotation.Cacheable;
    import org.springframework.cache.annotation.EnableCaching;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.stereotype.Repository;
    import org.springframework.test.context.ContextConfiguration;
    import org.springframework.test.context.junit4.SpringRunner;
    
    import com.hazelcast.core.Hazelcast;
    import com.hazelcast.core.HazelcastInstance;
    import com.hazelcast.spring.cache.HazelcastCacheManager;
    import com.hazelcast.test.TestHazelcastInstanceFactory;
    
    @RunWith(SpringRunner.class)
    @ContextConfiguration(
        classes= { CacheableTest.CacheConfig.class, CacheableTest.Repo.class }
        )
    @EnableCaching
    public class CacheableTest
    {
      @Configuration
      public static class CacheConfig
      {
        @Bean
        public HazelcastInstance hzInstance() {
          return Hazelcast.newHazelcastInstance();
        }
    
        @Bean
        public CacheManager cacheManager(HazelcastInstance hzInstance) {
            return new HazelcastCacheManager(hzInstance);
        }
      }
    
      @Repository
      public static class Repo {
    
        public static int callCountA;
        public static int callCountB;
    
        @Cacheable("a")
        public String getA(String key) {
          ++callCountA;
          return key;
        }
    
        @Cacheable("b")
        public String getB(String key) {
          ++callCountB;
          return key;
        }
    
      }
    
      @Autowired
      public Repo repo;
    
      @Test
      public void test() {
    
        String key = "a";
    
        assertEquals(0, Repo.callCountA);
        System.out.println(repo.getA(key));
        System.out.println(repo.getA(key));
        assertEquals(1, Repo.callCountA);
    
        assertEquals(0, Repo.callCountB);
        System.out.println(repo.getB(key));
        System.out.println(repo.getB(key));
        assertEquals(1, Repo.callCountB);
    
      }
    }