I have a Spring Boot application that is caching some values such as <UserId, MyPojo.class>.
Example MyPojo fields:
id
code
If a change is made to MyPojo.code then I want to clear the cache for all users that have that MyPojo.id.
I've looked at #CacheEvict annotation with a condition, but that seems to be only for deciding whether to evict cache on some condition without checking what is present in the cache itself.
Another option would be to iterate through every cache entry and check the value and clear that key, but that seems expensive.
Any suggestions?
Related
We would like to define our caches in our (spring boot) application similar to the concept varnish is doing with it's "grace mode". Right now we are using spring's #Cacheable annotation together with EhCache (but we are not bound to EhCache, if there's another cache backend able to to this would be fine, too).
Ideally I am searching for something like:
#Cacheable(cacheNames = "name", evictionAfter = "5 minutes", graceTimeAfterEviction = "1 minute")
public myCachedMethod() { ... }
What I mean is: If a value in the cache is already evicted (in this example 5+ minutes old) and a new request is asking for it, I want to return the already evicted value (to this request and all following until the new value is stored -- or the grace time passed, too), but still run the method asynchronously filling the cache with a new value.
Most of the approaches I have seen so far solve this by refreshing the cache programmatically with an asynchronous, scheduled task. But that's not what I want, as my cache entries depend on the arguments, and I don't want to keep old values if no one asks for them any more.
Of course, I know that this is not possible in this way, as spring is not aware of the cache management itself. And it can't be configured in the cache backend neither, because the cache backend has no idea of how to refresh the cache.
But maybe there is an approach out there, I did not find (I searched a lot for it already for a few years/months).
According to the documentation of caffeine cache this seems to be supported (https://github.com/ben-manes/caffeine, "https://github.com/ben-manes/caffeine"), but the documentation is, again, only about scheduled refreshes, no grace period. And it does not work with spring's annoations.
There is a similar question here: Spring cacheable asynchronous update while returns old cache, but more focussed on the sync=true feature.
I am trying to load my cache off of a cold start, prior to application startup. This would be done so values are available as soon as a user accesses a server, rather than having to hit my database.
#Cacheable functionality from Spring all works great, the problem is how I manually store objects in the Cache so that they can be read when the function is executed.
Spring is storing these objects in bytes, somehow -- and I need to mimic this while I manually load the cache. I'm just trying to figure out how they process the return objects, in the function, to store into the cache in a key,val pair.
You can programmatically access any cache by using Spring's CacheManager.
See https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/cache/CacheManager.html
var cache = cacheManager.getCache("foo");
cache.put(key, value);
I was able to solve this problem by storing values as a string key and object value -- which works wonderfully with Spring #Cacheable annotations. Objects are casted into the return types by Spring if they are found within the cache.
I realise #Cacheable annotation helps me with caching the result of a particular method call and subsequent calls are returned from the cache if there are no changes to arguments etc.
I have a requirement where I'm trying to minimise the number of calls to a db and hence loading the entire table. However,I would like to reload this data say every day just to ensure that my cache is not out of sync with the underlying data on the database.
How can I specify such reload/refresh intervals.
I'm trying to use Spring boot and hazelcast.All the examples I have seen talk about specifying LRU LFU etc policies on the config file for maps etc but nothing at a method level.
I can't go with the LRU/LFU etc eviction policies as I intend to reload the entire table data every x hrs or x days.
Kindly help or point me to any such implementation or docs etc.
Spring #Cacheable doesn't support this kind of policies at method level. See for example the code for CacheableOperation.
If you are using hazelcast as your cache provider for spring, you can explicitly evict elements or load datas by using the corresponding IMap from your HazelcastInstance.
This question is with reference to Simple Spring memcached.
I have a scenario where a list of deals are cached for user using the userId as the key. Now in case a deal data is updated I need to flush the cache for all users since this would affect deals data for all the users.
How can I achieve this with SSM annotations. The invalidate*cache and update*cache options seem to invalidate/update key specific cache entries whereas I need to clear the entire cache.
Currently it's impossible in plain SSM to flush entire cache using annotations, if you require such option please create a feature request on: https://code.google.com/p/simple-spring-memcached/issues/list
There is another way to flush entire cache by using SSM with Spring Cache as describer here: https://code.google.com/p/simple-spring-memcached/wiki/Getting_Started#Spring_3.1_Cache_Integration.
Just change allowClear to 'true' and use #CacheEvict(value = YOUR_CACHE_NAME, allEntries = true)
I have to integrate spring and ehcache, and trying to implement it with blockingCache pattern
<ehcache:annotation-driven/>
there is one option for self-populating-cache-scope for shared (default) and method. could you please explain what is the difference?
There is also the annotation #Cacheable with selfPopulating flag
As per what I read on some post
http://groups.google.com/group/ehcache-spring-annotations/browse_thread/thread/7dbc71ce34f6ee19/b057610167dfb815?lnk=raot
it says when shared is used only one instance is created and the same is used everytime the same cache name is used so if I use the selfPopulating flag as true for one method,
all the threads trying to access other methods annotated with
#Cacheable with selfPopulating flag set to true will go on hold which
I dont want
<ehcache:annotation-driven/>
when self-populating-cache-scope = method on other hand creates separate instances for all methods annotated with #Cacheable with selfPopulating flag set to true so it doesn't create a problem.
But in this case when I try to remove a element using #TriggerRemove and giving the cache name used in #Cacheable will it search in each of those separate instances to find the value? Isnt this an overhead?
Answered by Eric on the ehcache google group above
In all cases there is one underlying Ehcache instance. What happens
when you set selfPopulating=true is a SelfPopulatingCache wrapper is
created.
If cache-scope=shared then all annotations using that named cache will
use the same SelfPopulatingCache wrapper If cache-scope=method then
one wrapper is created per method
Note in both cases the SelfPopulatingCache is a wrapper, there is
still only one actual cache backing the wrapper(s)
As for blocking, If you read the docs for SelfPopulatingCache and
BlockingCache you'll notice that ehcache does a compromise between
cache level locking and per-key locking via key striping.
http://ehcache.org/apidocs/net/sf/ehcache/constructs/blocking/BlockingCache.html