Reputation: 21596
I am using Spring3.1 in standalone Env. I am caching my entry using @Cachable annotation.
Sometimes I need to iterate on the caching list in order to get specific value(not key).
So I managed to retrieve the cached list but how could I iterate on it's elements.
private ClientDTO getClientDTOByClientId(Integer clientId)
{
Cache clientCache = null;
try
{
clientCache = ehCacheCacheManager.getCache("client");
//need here to iterate on clientCache. how?
}
catch (Exception e)
{
log.error("Couldnt retrieve client from cache. clientId=" + clientId);
}
return clientDTO;
}
I using ehcache mechanism.
<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager"
p:cache-manager-ref="ehcache" />
<bean id="ehcache"
class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"
p:config-location="classpath:ehcache.xml" />
thanks, ray.
Upvotes: 12
Views: 54850
Reputation: 560
Another solution, cast org.springframework.cache.Cache to javax.cache.Cache by using getNativeCache() method and use java iterator as javax.cache.Cache already extends Iterable<Cache.Entry<K, V>>.
for more details read javax.cache.Cache javadoc
Cache cache = (Cache) cacheManager.getCache("yourCacheName").getNativeCache();
Iterator<Cache.Entry> iterator = cache.iterator();
while (iterator.hasNext()) {
String key = (String) iterator.next().getKey();
System.out.println(key);
}
Upvotes: 10
Reputation: 61
var cache = cacheManager.getCache("CACHE_NAME");
var nativeCache = (ConcurrentHashMap<?, ?>) cache.getNativeCache();
for (var entry: nativeCache.entrySet()){
// Access entry key and value
entry.getKey()
entry.getValue()
}
Upvotes: 2
Reputation: 672
I use this
first endpoint will tell you the caches you have
second endpoint will give you all the entries for a specific cache (with safe mapping)
third endpoint will give you all the entries for all your caches (with safe mapping)
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.github.benmanes.caffeine.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentMap;
@RestController
@RequestMapping("cache")
public class CacheController {
private final CacheManager cacheManager;
private final ObjectMapper objectMapper;
public CacheController(final CacheManager cacheManager) {
this.cacheManager = cacheManager;
this.objectMapper = new ObjectMapper();
this.objectMapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
this.objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
}
@GetMapping("/names")
public Collection<String> getCacheNames() {
return cacheManager.getCacheNames();
}
@GetMapping("{cacheName}")
public Map<String, Object> getEntriesForCache(@PathVariable(name = "cacheName") final String cacheName) throws JsonProcessingException {
final Cache<String, Object> cache = (Cache<String, Object>) cacheManager.getCache(cacheName).getNativeCache();
final ConcurrentMap<String, Object> data = cache.asMap();
final String json = objectMapper.writeValueAsString(data);
final TypeReference<HashMap<String,Object>> typeRef = new TypeReference<>() {};
return objectMapper.readValue(json, typeRef);
}
@GetMapping("entries")
public Map<String, Map<String, Object>> getAllEntries() throws JsonProcessingException {
final Map<String, Map<String, Object>> entries = new HashMap<>();
for(final String cacheName: getCacheNames()){
entries.put(cacheName, getEntriesForCache(cacheName));
}
return entries;
}
}
Upvotes: 0
Reputation: 47
The below method will give a set of keys of cached objects, But here if you add your cache with keys then it's easy to retrieve(If you add directly list of objects to cache then it'll not work out).
Also, I used GuavaCache in the cache manager like below.
@Bean
public CacheManager cacheManager() {
SimpleCacheManager simpleCacheManager = new SimpleCacheManager();
GuavaCache userLabCache = new GuavaCache("yourCacheName",
CacheBuilder.newBuilder().expireAfterAccess(5, TimeUnit.MINUTES).build());
simpleCacheManager.setCaches(Arrays.asList(userLabCache));
return simpleCacheManager;
}
Then it'll return the list of keys as objects, then you'll get the keys and you can iterate through keys and get the objects one by one from the cache.
Autowire Springboot CacheManager in your class
@Autowired
CacheManager cacheManager;
below is the code to get all keys.
public Set<Object> getAllCachedUserLabKeys() {
Set<Object> keys = null;
try {
GuavaCache cache = (GuavaCache) cacheManager.getCache("yourCacheName");
if (cache != null) {
ConcurrentMap<Object, Object> cachedMap = cache.getNativeCache().asMap();
keys = cachedMap.keySet();
}
} catch (Exception e) {
LOGGER.error("Unknown exception occured while fetchting all cached User Labs..!", e);
}
return keys;
}
Upvotes: 1
Reputation: 5391
CacheManager.getCache() returns a net.sf.ehcache.Cache, which has a getKeys() method that returns a list of cache keys that you can iterate over. To retrieve the actual object that's been stored (as opposed to the wrapped net.sf.ehcache.Element), use the Element.getObjectValue().
EDIT: According to Spring it doesn't look like they will ever support Cache.getKeys(), so you'll have to cast to the underlying provider.
Something like this:
public boolean contains(String cacheName, Object o) {
net.sf.ehcache.EhCache cache = (net.sf.ehcache.EhCache) org.springframework.cache.CacheManager.getCache(cacheName).getNativeCache();
for (Object key: cache.getKeys()) {
Element element = cache.get(key);
if (element != null && element.getObjectValue().equals(o)) {
return true;
}
}
return false;
}
Upvotes: 18