@CachePut(cacheNames = "projectTeams", key = "#projectTeam.id")
public List<ProjectTeam> updateAll(List<ProjectTeam> projectTeam) {
return projectTeamRepository.save(projectTeam);
}
@Cacheable(cacheNames = "projectTeams", key = "#id")
public List<ProjectTeam> findByIds(ListOfIds<Long> ids) {
log.info("get project team from db");
log.info("projectTeam id " + id);
return projectTeamRepository.findByIds(ids);
}
I don't have any idea what i should put in key. Does spring cache supports SaveAll.
Spring uses a default key generation strategy to derive the key for the cache entry from the caching-enabled (
@Cacheableor@CachePutannotated) service or repository methods based on the arguments to the method.Of course, you can customize key generation used by any cache-enabled bean methods by 1) implementing the
KeyGeneratorinterface and 2) declaring theKeyGeneratorbean in your caching annotations, like so:In configuration, you would declare:
You would apply the custom
KeyGeneratorusing:However, you do not necessarily need a custom
KeyGeneratorif you simply rely on Spring's default key generation strategy as I mentioned to begin with.Regarding the approach you chose, this will not work since it is trying to use a Spring SpEL expression to access a single element/item (i.e. a single
ProjectTeaminstance) in aListofProjectTeamobjects. Same applies for theListof IDs.Which element from the
Listdo you use? Do you use all elements (which would be difficult to aggregate using SpEL)? What happens if theListargument to the cache-enabled method is empty, or worse,null?These sort of concerns are more appropriately handled in your custom
KeyGeneratorimplementation.You should also be aware that the cached entries for the cache-enabled methods of your Spring managed bean will be (using "default key generation"):
If you are expecting the individual elements/items (e.g. either
LongIDs orProjectTeaminstances) of theListsto be broken out and cached individually in separate cache entries, then you are mistaken because this is NOT how Spring's Cache Abstraction works by default.The reason I mention this is because it is sort of implied by your (attempted) caching configuration as declared in the annotations.
Spring takes the argument(s) to the cache-enabled method (e.g.
@Cacheableannotated method) and uses that as a key for the cache entry. The return value of the method is used as the value. Since the cache-enabled methods take aListand return aListthen the cache entry key is theListargument and theListreturn value is the cache entry value.As you might imagine, with each different
Listof IDs orListofProjectTeaminstances requested, your cache memory space is going to fill up fast! That is because if theListin each request (cache-enable method) just differs by 1 element, then that is going to constitute a new cache entry in the cache. Depending on how many (different) requests (invocations) your application processes, and the frequency, this could lead to a serious problem (e.g. OOME)!If you need individual cache entries for individually requested items, then you should have a look at this SO post from earlier.
Good luck!