@CachePut or @Cacheable(value = "CustomerCache", key = "#id") public Customer updateCustomer(Customer customer) { sysout("i am inside updateCustomer"); .... return customer; }
I found below documentation under CachePut
source code
CachePut annotation does not cause the target method to be skipped - rather it always causes the method to be invoked and its result to be placed into the cache.
Does it mean if I use @Cacheable
, updateCustomer method will be executed only once and result will be updated in cache. Subsequent calls to updateCustomer will not execute updateCustomer , it will just update the cache.
While in case of @CachePut
, updateCustomer
method will be executed on each call and result will be updated in cache.
Is my understanding correct?
@CachePut always lets the method execute. It is generally used if you want your cache to be updated with the result of the method execution. Example: When you want to update a stale data which is cached, instead of blowing the cache completely.
As the name implies, @Cacheable is used to demarcate methods that are cacheable - that is, methods for whom the result is stored into the cache so on subsequent invocations (with the same arguments), the value in the cache is returned without having to actually execute the method.
Spring Cache uses the parameters of the method as key and the return value as a value in the cache. When the method is called the first time, Spring will check if the value with the given key is in the cache. It will not be the case, and the method itself will be executed.
Yes.
I even made a test to be sure:
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = CacheableTest.CacheConfigurations.class) public class CacheableTest { public static class Customer { final private String id; final private String name; public Customer(String id, String name) { this.id = id; this.name = name; } public String getId() { return id; } public String getName() { return name; } } final public static AtomicInteger cacheableCalled = new AtomicInteger(0); final public static AtomicInteger cachePutCalled = new AtomicInteger(0); public static class CustomerCachedService { @Cacheable("CustomerCache") public Customer cacheable(String v) { cacheableCalled.incrementAndGet(); return new Customer(v, "Cacheable " + v); } @CachePut("CustomerCache") public Customer cachePut(String b) { cachePutCalled.incrementAndGet(); return new Customer(b, "Cache put " + b); } } @Configuration @EnableCaching() public static class CacheConfigurations { @Bean public CustomerCachedService customerCachedService() { return new CustomerCachedService(); } @Bean public CacheManager cacheManager() { return new GuavaCacheManager("CustomerCache"); } } @Autowired public CustomerCachedService cachedService; @Test public void testCacheable() { for(int i = 0; i < 1000; i++) { cachedService.cacheable("A"); } Assert.assertEquals(cacheableCalled.get(), 1); } @Test public void testCachePut() { for(int i = 0; i < 1000; i++) { cachedService.cachePut("B"); } Assert.assertEquals(cachePutCalled.get(), 1000); } }
@CachePut always lets the method execute. It is generally used if you want your cache to be updated with the result of the method execution.
Example: When you want to update a stale data which is cached, instead of blowing the cache completely.
@Cacheable will be executed only once for the given cachekey and subsequent requests won't execute the method, until the cache expires or gets flushed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With