There are scenarios, unlike retrievals, where you do not want to skip the execution of the method e.g. insert/update of a record. Such methods should not be marked as Cacheable. But, you might still want to cache the result of these methods, in order to avoid unnecessary retrievals in future calls.
For such cases, there is
CachePut
. When a method, annotated with @CachePut
, is invoked.- The method is always executed.
- The result of the method is then put into the cache.
Let's check out a few examples for better understanding.
public class ActorService {
@CachePut(value = "actors", key = "#actor.name")
public Actor addActor(Actor actor) {
//persist the actor
System.out.println("Adding actor " + actor.getName());
return actor;
}
@Cacheable(value = "actors", key = "#name")
public Actor getActor(String name) {
System.out.println("getting actor " + name);
//retrieve the actor from DB and return
return new Actor(name, Gender.MALE);
}
}
And below is the test code that adds an actor and then tries to retrieve it (twice).
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext("com.codelooru.cache");
ActorService service = context.getBean("actorService", ActorService.class);
service.addActor(new Actor("Sean Connery", Gender.MALE));
service.getActor("Sean Connery");
service.addActor(new Actor("Sean Connery", Gender.MALE));
service.getActor("Sean Connery");
Execution of the test prints the following on the console.
Adding actor Sean Connery
Adding actor Sean Connery
As you see, the addActor() method is executed both the times. Whereas, the getActor() wasn't executed at all.
Note: All attributes, including
condition
and unless
, that are applicable to Cacheable
are also applicable to CachePut
and work exactly the same way.Please check Part 1, Part 2, Part 3 of Spring Cache article, if you haven't already done so.