Lakshmi Narasimhan
Lakshmi Narasimhan

Reputation: 1

Is there a way to use one Hazelcast configuration across multiple cachings?

I want to cache user data and their Accounts data. The key for both is User ID.

I would like to know how to implement caching across user data and Accounts data using one Hazelcast config ? Or

Should i use two separate Hazelcast instances

config.addMapConfig(
       new MapConfig()
        .setName("CS_DATA")
        .setMaxSizeConfig(new 
                  MaxSizeConfig(Integer.parseInt(cacheSize),                                                        
                  MaxSizeConfig.MaxSizePolicy.valueOf(cachePolicy)))
        .setEvictionPolicy(EvictionPolicy.LRU)                                    
        .setTimeToLiveSeconds(Integer.parseInt(cacheTTL)));
        return config;
    }

=============

@Cacheable(value = "CS_DATA", key = "#userName" , condition = "#root.target.isAccountCacheRequired()")
public Object getAccounts(String userName) {
            log.info("Cache miss for Accounts data.....Calling otlClient ...." );

=============

@Cacheable(value =CS_DATA, key = "#userName", condition = "#root.target.isUserCacheRequired()")

public User getUser(String userName) {
   log.info("Cache miss for UserData.....Calling otlClient ...." );
  }

====== The current problem that i'm facing is, it overwrites the data as key is same across user and accounts. Any help here would be great

Upvotes: 0

Views: 603

Answers (1)

Vassilis Bekiaris
Vassilis Bekiaris

Reputation: 823

Your data is being overwritten because you use the same cache name in both Cacheable annotations (both indicate spring should write to the cache with name CS_DATA).

You should make sure you use separate caches (Hazelcast IMaps) for each different type you cache (I assume the return type for getAccounts is not a User object as is the case for getUser). For example, you can annotate your cacheable methods like this to use a CS_ACCOUNT IMap for caching accounts and a separate CS_USER IMap for User objects:

@Cacheable(value = "CS_ACCOUNT", key = "#userName" , condition = "#root.target.isAccountCacheRequired()")
public Object getAccounts(String userName) {
            ...
}

@Cacheable(value = "CS_USER", key = "#userName", condition = "#root.target.isUserCacheRequired()")
public User getUser(String userName) {
   ...
}

If you want to configure the two separate IMaps with a different configuration, you can use two separate MapConfigs in your Hazelcast Config like this:

public Config getConfig() {
  config.addMapConfig(
    new MapConfig()
      .setName("CS_ACCOUNT")
      .setMaxSizeConfig(new MaxSizeConfig(Integer.parseInt(cacheSize),                                                        
                  MaxSizeConfig.MaxSizePolicy.valueOf(cachePolicy)))
      .setEvictionPolicy(EvictionPolicy.LRU)                                    
      .setTimeToLiveSeconds(Integer.parseInt(cacheTTL)));
  // add another map config for CS_USER IMap
  config.addMapConfig(
    new MapConfig()
      .setName("CS_USER")
      .setMaxSizeConfig(new MaxSizeConfig(Integer.parseInt(userCacheSize),                                                        
                  MaxSizeConfig.MaxSizePolicy.valueOf(cachePolicy)))
      .setEvictionPolicy(EvictionPolicy.LRU)                                    
      .setTimeToLiveSeconds(Integer.parseInt(userCacheTTL)));

  return config;
}

If you want multiple IMaps to share common configuration, then you can use wildcards in configuration. For example, in order to have all IMaps starting with CS_ share a common configuration, use CS_* as the map name in MapConfig like this:

public Config getConfig() {
  // all IMaps with name starting with CS_ will share same max size config, eviction policy and TTL
  config.addMapConfig(
    new MapConfig()
      .setName("CS_*")
      .setMaxSizeConfig(new MaxSizeConfig(Integer.parseInt(cacheSize),                                                        
                  MaxSizeConfig.MaxSizePolicy.valueOf(cachePolicy)))
      .setEvictionPolicy(EvictionPolicy.LRU)                                    
      .setTimeToLiveSeconds(Integer.parseInt(cacheTTL)));
  return config;
}

Upvotes: 1

Related Questions