Nice video, easily understandable. Thanks. I read 2 articles on Baeldung and Javatpoint and couldn't understand what different annotations were used for but your video helped me.
Yes, if you have two update methods that update the same Book object and you want to cache the Book object after each update, you would need to use @CachePut annotation twice. Here's an example: @Service public class BookService { private Map bookCache = new HashMap(); @CachePut(value = "bookCache", key = "#book.id") public Book updateBookTitle(Long id, String newTitle) { Book book = bookCache.get(id); book.setTitle(newTitle); bookCache.put(id, book); return book; } @CachePut(value = "bookCache", key = "#book.id") public Book updateBookAuthor(Long id, String newAuthor) { Book book = bookCache.get(id); book.setAuthor(newAuthor); bookCache.put(id, book); return book; } @Cacheable(value = "bookCache", key = "#id") public Book getBookById(Long id) { // Code to retrieve book return bookCache.get(id); } }
Thank you, this is very helpful. However, I'll like to know how to handle the case of caching a list. Say for instance, a call was made to a 3rd party API that returns a list, how best should one handle caching such data.
Great question!! If the list is static and doesn't change often, then caching the list is a good approach. However, if the list changes frequently, caching may not be the best solution, as the cached data may become stale quickly. @Service public class DataService { @Cacheable("dataList") // this is the line that will do the job of caching public List getData() { // Call third-party API to retrieve data List dataList = thirdPartyApi.getData(); return dataList; } } ======================================= It's important to set an expiration time for the cache to ensure that stale data is not served. You can set the expiration time by using the @CacheConfig annotation and specifying the cache expiration time in seconds. @Service @CacheConfig(cacheNames = "dataList", cacheManager = "cacheManager") public class DataService { @Cacheable(key = "#root.methodName") @CacheEvict(key = "#root.methodName", allEntries = true) public List getData() { // Call third-party API to retrieve data List dataList = thirdPartyApi.getData(); return dataList; } } In the above example, the @CacheConfig annotation is used to specify the cache name and cache manager to be used. The @Cacheable and @CacheEvict annotations are used to cache and evict the cache respectively.
On the first call maybe there is cache miss....that's tricky part in using cache if the data is not found in cache then there is one more extra network hop
While caching am passing multiple arguments as key in redis then how to delete entry from redis using cache evict? How to pass that multiple argument in key field
Hi Green Learner How to set custom cache value? Scenario: @CachePut - You are returning Book object, so the Book object is caching. In my use case, returning boolean/Status while updating (by passing the Book object to the method). So I want to cache the Book object not a boolean/Status value. Hope you will reply, Thank you in Advance.
To set a custom cache value when using the @CachePut annotation in Spring Boot, you can use the unless attribute of the @CachePut annotation. The unless attribute allows you to conditionally cache the value based on a SpEL (Spring Expression Language) expression. In your case, you can modify the @CachePut annotation to cache the Book object instead of the boolean/Status value. Here's an example: @Service public class BookService { private Map bookCache = new HashMap(); @CachePut(value = "bookCache", key = "#book.id", unless = "#result == false") public boolean updateBook(Book book) { // Code to update book boolean status = true; if (book != null) { bookCache.put(book.getId(), book); } else { status = false; } return status; } @Cacheable(value = "bookCache", key = "#id") public Book getBookById(Long id) { // Code to retrieve book return bookCache.get(id); } } In this example, the @CachePut annotation is used to cache the Book object with the key "#book.id". The unless attribute is used to conditionally cache the value based on the result of the update operation. If the update is successful (i.e., the result is true), the Book object is cached. If the update is unsuccessful (i.e., the result is false), the Book object is not cached. Note that in order for the cache to work correctly, the Book object must have a unique identifier, such as an ID field, that can be used as the cache key. In this example, we assume that the Book object has an "id" field that can be used as the key.
how ? it took longer time to get data from the cache than from the db. can someone explain to me why? .concentrate on the time in postman after the status
At first call it will take time...as it's getting data from db and then putting it in cache and then returning to the client. All the subsequent calls will be quick for the same request. Keep in mind the data should be present in cache for it to be fast
How does getBook work when db is changed without using the put method? For example.. the name of book id : 42 is changed to something else after it gets cached. How does it give correct information if it doesn't make db call?
In caching we have to make sure that get and update calls goes through cache also so that cache also get updated. If you change something from DB which is already cached then cached data won't be changes. It's developer responsibility to take care of this.
It will work but each instance will have its own cache. Usually in such cases where we have multiple instance we use distributed cache as well. Redis, Hazlecast are good options to consider for distributed caching
To do this, you need to specify the key attribute of the @CacheEvict annotation with a SpEL. @CacheEvict(value = "myCache", key = "{#param1, #param2}") public void evictCachedData(String param1, String param2) { // This method will evict the cached entry with the specified parameters }
@@codefarm0 Same doubt sir. He meant for update or PUT we have CachePut, for GET we have Cachable, for delete or DELETE we have evict, then what about POST or insert/add in DB....will it keep data in cache first then insert new data in DB? or if it will verify first in cache about new data which is suppose to be inserted is already available in cache and then based on it will or wont insert the new data in DB?
this is good .. can you cache all records of a table ( assuming it's just 20 to 50 records ) thru commandline runner before it accepts the request (get method) so all keys are already cache prior to first get ? thanks
1. Add Dependencies: Include the caching provider dependency in your project. 2. Enable Caching: Use @EnableCaching in your main application class. 3. Configure Caching: Set up caching configurations in your properties file. 4. Load Data at Startup: Use @PostConstruct to load and cache data at boot up, I think this is what you specifically looking for. 5. Apply Caching: Use @Cacheable to cache method results.
1.How is it implemented in application 2.What functionalities in application utilizes caching 3.How do you identify that a method uses caching from code Kindly reply to this message
This is the first concise, clear, and yet comprehensive video I've been able to find on this topic, thank you for the work you put into these! :)
This is exactly what I was looking for, and explained short and sweet ! kudos !
Glad you liked it!
Nice video, easily understandable. Thanks. I read 2 articles on Baeldung and Javatpoint and couldn't understand what different annotations were used for but your video helped me.
That's awesome...happy to see that you got it clear...let me know if have any followup ques
your presenting technique is really good. please continue
👍
Perfectly demonstrated, It became very easily understand now. Thank you.
Glad it was helpful!
Well explained. Thank You
found exactly what i was looking for , thank you :-)
Glad I could help!
Nicely explained!
Thanks Brother
Niceoverview! Good video! thanks
Glad you liked it!
Simple and great explanation..
Glad it was helpful!
V good explanation. Thanks.. subscribed ur channel
Thanks @Rinku
Thank you ❤️ nice explained
Glad it was helpful!
awesome explained...
findAll () method what will be the key inside cacheble annotations?
Awesome, one of the best and simpler to understand,thanks buddy
Glad you liked it!
Thank bro...❤
This is good! To the point.
Thanks buddy well explained
Crisp Explanation, but needed something more to apply in more complex cases.
yea...will try to come up with some more demos around this
Thank you!
Welcome!
Which cache is being getting used here by default?
Hey mate very good video and clearly demonstrated! But what if I have two updates methods one after another? Should i use two times @CachePut ?
Yes, if you have two update methods that update the same Book object and you want to cache the Book object after each update, you would need to use @CachePut annotation twice.
Here's an example:
@Service
public class BookService {
private Map bookCache = new HashMap();
@CachePut(value = "bookCache", key = "#book.id")
public Book updateBookTitle(Long id, String newTitle) {
Book book = bookCache.get(id);
book.setTitle(newTitle);
bookCache.put(id, book);
return book;
}
@CachePut(value = "bookCache", key = "#book.id")
public Book updateBookAuthor(Long id, String newAuthor) {
Book book = bookCache.get(id);
book.setAuthor(newAuthor);
bookCache.put(id, book);
return book;
}
@Cacheable(value = "bookCache", key = "#id")
public Book getBookById(Long id) {
// Code to retrieve book
return bookCache.get(id);
}
}
Thank you, this is very helpful.
However, I'll like to know how to handle the case of caching a list. Say for instance, a call was made to a 3rd party API that returns a list, how best should one handle caching such data.
Great question!!
If the list is static and doesn't change often, then caching the list is a good approach. However, if the list changes frequently, caching may not be the best solution, as the cached data may become stale quickly.
@Service
public class DataService {
@Cacheable("dataList") // this is the line that will do the job of caching
public List getData() {
// Call third-party API to retrieve data
List dataList = thirdPartyApi.getData();
return dataList;
}
}
=======================================
It's important to set an expiration time for the cache to ensure that stale data is not served. You can set the expiration time by using the @CacheConfig annotation and specifying the cache expiration time in seconds.
@Service
@CacheConfig(cacheNames = "dataList", cacheManager = "cacheManager")
public class DataService {
@Cacheable(key = "#root.methodName")
@CacheEvict(key = "#root.methodName", allEntries = true)
public List getData() {
// Call third-party API to retrieve data
List dataList = thirdPartyApi.getData();
return dataList;
}
}
In the above example, the @CacheConfig annotation is used to specify the cache name and cache manager to be used. The @Cacheable and @CacheEvict annotations are used to cache and evict the cache respectively.
Awesome Video👏👏 Pls make a video on comparable future as well for multithreading
Noted
Really appreciate Bro
Great explanation !
But I wonder why getting the Book from database took 89ms and getting it from the cache took 111ms (As per postman)
On the first call maybe there is cache miss....that's tricky part in using cache if the data is not found in cache then there is one more extra network hop
While caching am passing multiple arguments as key in redis then how to delete entry from redis using cache evict? How to pass that multiple argument in key field
I think key can be only one.
you can try making composite key by combining the multiple arguments
Hi Green Learner
How to set custom cache value?
Scenario: @CachePut - You are returning Book object, so the Book object is caching.
In my use case, returning boolean/Status while updating (by passing the Book object to the method). So I want to cache the Book object not a boolean/Status value.
Hope you will reply, Thank you in Advance.
To set a custom cache value when using the @CachePut annotation in Spring Boot, you can use the unless attribute of the @CachePut annotation. The unless attribute allows you to conditionally cache the value based on a SpEL (Spring Expression Language) expression.
In your case, you can modify the @CachePut annotation to cache the Book object instead of the boolean/Status value. Here's an example:
@Service
public class BookService {
private Map bookCache = new HashMap();
@CachePut(value = "bookCache", key = "#book.id", unless = "#result == false")
public boolean updateBook(Book book) {
// Code to update book
boolean status = true;
if (book != null) {
bookCache.put(book.getId(), book);
} else {
status = false;
}
return status;
}
@Cacheable(value = "bookCache", key = "#id")
public Book getBookById(Long id) {
// Code to retrieve book
return bookCache.get(id);
}
}
In this example, the @CachePut annotation is used to cache the Book object with the key "#book.id". The unless attribute is used to conditionally cache the value based on the result of the update operation. If the update is successful (i.e., the result is true), the Book object is cached. If the update is unsuccessful (i.e., the result is false), the Book object is not cached.
Note that in order for the cache to work correctly, the Book object must have a unique identifier, such as an ID field, that can be used as the cache key. In this example, we assume that the Book object has an "id" field that can be used as the key.
Man, this is so so helpful. Thanks a lot. Do you have any plans to cover Junit and Mockito?
glad to hear that it was helpful.
for mockito and junit >> its already on the channel..please search
we cn use @cacheput for addbook also,but we are not using it , any reason for this
how ? it took longer time to get data from the cache than from the db. can someone explain to me why? .concentrate on the time in postman after the status
At first call it will take time...as it's getting data from db and then putting it in cache and then returning to the client. All the subsequent calls will be quick for the same request. Keep in mind the data should be present in cache for it to be fast
Tq
How does getBook work when db is changed without using the put method?
For example.. the name of book id : 42 is changed to something else after it gets cached. How does it give correct information if it doesn't make db call?
In caching we have to make sure that get and update calls goes through cache also so that cache also get updated. If you change something from DB which is already cached then cached data won't be changes. It's developer responsibility to take care of this.
If we use native queries in repo for DB call CRUD operations then how can we use these cache implementations please suggest
You can use them as it's...I don't think there will be any issue .
Will this cache mechanism work fine if multiple instances of the application are running?
It will work but each instance will have its own cache. Usually in such cases where we have multiple instance we use distributed cache as well. Redis, Hazlecast are good options to consider for distributed caching
how to use cachEvict when you have two parameters
To do this, you need to specify the key attribute of the @CacheEvict annotation with a SpEL.
@CacheEvict(value = "myCache", key = "{#param1, #param2}")
public void evictCachedData(String param1, String param2) {
// This method will evict the cached entry with the specified parameters
}
Thank you! ;)
welcome :)
What about the insert ??
Of what??
@@codefarm0 Same doubt sir. He meant for update or PUT we have CachePut, for GET we have Cachable, for delete or DELETE we have evict, then what about POST or insert/add in DB....will it keep data in cache first then insert new data in DB? or if it will verify first in cache about new data which is suppose to be inserted is already available in cache and then based on it will or wont insert the new data in DB?
New data no need to be cached while insertion right..question doesn't make sense
Awesome , how can we implement real time service in spring boot
you can checkout the playlists on the channel, there are many real time service in spring boot
ua-cam.com/users/GreenLearnerplaylists
this is good .. can you cache all records of a table ( assuming it's just 20 to 50 records ) thru commandline runner before it accepts the request (get method) so all keys are already cache prior to first get ? thanks
Definitely we can do that. I need to check about how to access the Spring Cache map in the runner method.
@@codefarm0 - I've done it -thanks
How do I cache at boot up and store it
1. Add Dependencies: Include the caching provider dependency in your project.
2. Enable Caching: Use @EnableCaching in your main application class.
3. Configure Caching: Set up caching configurations in your properties file.
4. Load Data at Startup: Use @PostConstruct to load and cache data at boot up, I think this is what you specifically looking for.
5. Apply Caching: Use @Cacheable to cache method results.
awesome!
i tried this but hibernate querying twice for the same request.
That seems odd...anything in the logs??
Poor sound quality. Mic needs to be replaced
already done..appreciate the feedback
1.How is it implemented in application
2.What functionalities in application utilizes caching
3.How do you identify that a method uses caching from code
Kindly reply to this message