I am calling fetchCatchAndClear method where I am passing List and it consists of cache names. Can someone help me how to iterate over the list and clear the cache based on the Cache Name coming from List of String. Also if the list is empty I should clear all the caches present.
A rather simple approach which sticks to the org.springframework.cache.CacheManager could be the following:
List<String> cacheNames = List.of("aCache", "anotherCache"); // the list you are passing in
CacheManager cacheManager = new SimpleCacheManager(); // any cache manager you are injecting from anywhere
// a simple iteration, exception handling omitted for readability reasons
cacheNames.forEach(cacheName -> cacheManager.getCache(cacheName).clear());
Evicting all caches is also that simple, except that you have to query the relevant cache names from the very same cache manager:
CacheManager cacheManager = new SimpleCacheManager();
Collection<String> cacheNames = cacheManager.getCacheNames();
cacheNames.forEach(cacheName -> cacheManager.getCache(cacheName).clear());
If you just want to evict a single cache entry you could either do it programmatically like:
cacheManager.getCache(cacheName).evict(cacheKey); or annotation-based like
#CacheEvict(value = "yourCacheName", key = "#cacheKey")
public void evictSingleCacheValue(String cacheKey) {
}
#CacheEvict(value = "yourCacheName", allEntries = true)
public void evictAllCacheValues() {
}
Related
Hello guys i'm having a big big dilema, i have a methode cacheable with a hashSet, i want to delete this cache for all the cacheable data that contains a specific value in the HashSet. is it possible with cache evict ?
i want only the HashSet for example containing the value 25486 to be deleted. the allEntry=true deletes everyting.
my HashSet are random so i can't generate the same HashSet everytime.
do someone Knows how to resolve this problem ?? thank you
#Cacheable(value = "myCache", keyGenerator= MethodAndParamsKeyGenerator.KEY_GENERATOR_NAME)
public void getCutsom(Set<Long> ids){
//...
}
#CacheEvict(value = "myCache", keyGenerator= MethodAndParamsKeyGenerator.KEY_GENERATOR_NAME)
public void getCutsom(Set<Long> ids){
}
Situation: my spring-boot project has two objects in which I need to cache data. The problem is that the settings for expire time must be different for the two objects.
I found a lot of information on the web about how i can set up a cache manager, but I did not understand which of these methods can be used in modern industrial code.
Please tell me how to configure settings for 2 different cache managers and if you need cache managers at all? My head is in a mess.
p.s. I don't want to use third-party dependencies like ehcache.
example:
public class Repository1(){
#Cacheable("Repository1.findAllImportantThings")
public Map<Long, String> findAllImportantThings() {...}
}
public class Repository2(){
#Cacheable("Repository2.findOnlyOne")
public Map<Long, String> findOnlyOne(String id) {...}
}
There can be more methods in a class. But the point is that I need to set different TTLs for these two classes
When you want to have different cache TTL then you need cacheManager, if in case all the caches have same TTL then it is not required.
You can do it this way :
#Bean
fun cacheManager(connectionFactory: RedisConnectionFactory): RedisCacheManager {
val oneHourTTLCacheConfig = cacheConfigWithTTL(60) //TTL for cacheKey-1
val fourHoursTTLCacheConfig = cacheConfigWithTTL(240) //TTL for cacheKey-2
val cacheConfigurations = mapOf(
"cacheKey-1"
to oneHourTTLCacheConfig,
"cacheKey-2"
to fourHoursTTLCacheConfig
)
return RedisCacheManager.builder(connectionFactory)
.cacheDefaults(redisCacheConfiguration(CacheConfiguration.THIRTY_MINUTES_DEFAULT_TTL))
.withInitialCacheConfigurations(cacheConfigurations)
.build()
} // Sets default TTL to 30 minutes if the other cacheKeys don't require any different configuration
private fun cacheConfigWithTTL(ttlInMinutes: Long): RedisCacheConfiguration =
RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofMinutes(ttlInMinutes))
.disableCachingNullValues()
private fun redisCacheConfiguration(duration: Duration): RedisCacheConfiguration =
RedisCacheConfiguration
.defaultCacheConfig()
.entryTtl(duration)
You can add this to your cache configuration class. Let me know if you have any further question.
I have a impl class where I have 2 update methods , method1 is updating complete row in DB whereas method2 is updating only one column in DB of that table.
Now I need to use #Caceable and #CacheEvict here , How can I use in this condition ?
From Spring 3.1 introduces a new feature to allow methods to be cached and evicted thus allowing resource heavy methods to be avoided where possible. Caching is enabled via the new #Cacheable and #CacheEvict annotations.
One example of caching would be, for example, database activity. We can apply the #Cacheable annotation to a find operation and then apply the #CacheEvict to an update / delete operation. In this sense, caching would work much like a second level cache in Hibernate or JPA.
To enable caching on a find method, the method needs to be annotated with the #Cacheable annotation identifying which cache to use. Spring allows multiple caches to be defined each of which can be backed by a different caching abstraction.
#Cacheable("items") //#Cacheable(value = "items", key = "#itemId")
public Item find(long itemId) {
Item item = entityManager.find(Item.class, itemId);
return item;
}
When it is time to invoke the find method, Spring checks in the specified cache to see if the results of the operation have already been cached and if the results can be therefore be returned from cache instead of invoking the method. Spring uses the method arguments as the key, so in this case the itemId parameter.
To evict an entry from the cache when an object is updated in the database, the #CacheEvict annotation can be used. Again, this annotation takes a parameter identifying which cache to use.
#CacheEvict(value = "items", key = "#item.id")
public void updateItem(Item item) {
entityManager.merge(item);
}
EDIT:
#CacheEvict
Used for Cache-removal /cache-cleanup operation. #CacheEvict annotation indicates that a method (or all methods on a class) triggers a cache evict operation, removing specific [or all] items from cache. Various attributes provides complete control to enforce the required behavior for cache-eviction.
for example,
#CacheEvict(value = "products", key = "#product.name")
public void refreshProduct(Product product) {
//This method will remove only this specific product from 'products' cache.
}
#CacheEvict(value = "products", allEntries = true)
public void refreshAllProducts() {
//This method will remove all 'products' from cache, say as a result of flush-all API.
}
While using Spring's #Cacheable, how to make sure the cache does not last longer than the actual session timeout?
Suppose your caches are defined as below,
#Cacheable("cacheName1")
public Map<String, List<String>> getMethod1(){
}
#Cacheable("cacheName2")
public Map<String, List<String>> getMethod2(){
}
then call below method while the user clicks logout / session expires.
#CacheEvict(value = { "cacheName1", "cacheName2"}, allEntries = true)
public void evictAllCache(){
logger.info("All Cache Evict");
}
Extend CacheManager to handle bucket's name, e.g. #session_#name
Extend HttpSessionListener to make a clean up when session is destroyed
please find my draft sample of explicit cache per session below:
https://gist.github.com/pyanoveugen/b360622dc76136064b0215136f402837
In my code I am using EhCache to store an object. Code is below
#Resource(name = "ehCacheManager")
private CacheManager manager;
private Ehcache cache;
public void testCache(){
cache = manager.getCache("ehSubjects");
for loop to read subjects data{ //This loops runs 15051 times
final Element element = new Element(subject.subjectId(), subject);
cache.put(element);
}
}
System.out.println("Cache Size:"+cache.getSize()); //15000
The issue is there are 15051 subjects objects but when after the loop I try to print the cache size it always gives me 15000.
So is there a limit on the amount of objects we can keep in EhCache?
The issue was with the ehcache.xml defined by the other team mate. He has given the maxitemsincache value as 15000 due to which cahce was ignoring other items.