Spring Framework provides an abstraction layer with set of annotations for caching support and can work together with various cache implementation like Redis, EhCache, Hazelcast, Infinispan and many more.
@Cacheable
Fulfill cache after method execution, next invocation with the same arguments will be omitted and result will be loaded from cache. Annotation provide useful feature called conditional caching. In some case no all data should be cached e.g. you want store in memory only most popular posts.
@Cacheable(value = "post-single", key = "#id", unless = "#result.shares < 500")
@GetMapping("/{id}")
public Post getPostByID(@PathVariable String id) throws PostNotFoundException {
log.info("get post with id {}", id);
return postService.getPostByID(id);
}
@Cacheable(value = "post-top")
@GetMapping("/top")
public List<Post> getTopPosts() {
return postService.getTopPosts();
}
@CachePut
Annotation allows to update entry in cache and support same options like Cacheable annotation. Code below updates post and return it for cache provider to change entry with new value.
@CachePut(value = "post-single", key = "#post.id")
@PutMapping("/update")
public Post updatePostByID(@RequestBody Post post) throws PostNotFoundException {
log.info("update post with id {}", post.getId());
postService.updatePost(post);
return post;
}
@CacheEvict
Remove entry from cache, can be both conditional and global to all entries in specific cache.
@CacheEvict(value = "post-single", key = "#id")
@DeleteMapping("/delete/{id}")
public void deletePostByID(@PathVariable String id) throws PostNotFoundException {
log.info("delete post with id {}", id);
postService.deletePost(id);
}
@CacheEvict(value = "post-top")
@GetMapping("/top/evict")
public void evictTopPosts() {
log.info("Evict post-top");
}
@EnableCaching
Annotation ensure that post processor will check all beans trying to find demarcated methods and will create proxy to intercept all invocations.
@Caching
Aggregate multiple annotations of the same type when e.g. you need to use different conditions and caches.
@CacheConfig
Class level annotation allows to specify global values for annotations like cache name or key generator.
Hibernate Second-Level Cache
One of the advantages of database abstraction layers such as ORM (object-relational mapping) frameworks is their ability to transparently cache data retrieved from the underlying store. This helps eliminate database-access costs for frequently accessed data.
What Is a Second-Level Cache?
As most other fully-equipped ORM frameworks, Hibernate has the concept of first-level cache. It is a session scoped cache which ensures that each entity instance is loaded only once in the persistent context.
Once the session is closed, first-level cache is terminated as well. This is actually desirable, as it allows for concurrent sessions to work with entity instances in isolation from each other.
On the other hand, second-level cache is SessionFactory-scoped, meaning it is shared by all sessions created with the same session factory. When an entity instance is looked up by its id (either by application logic or by Hibernate internally, e.g. when it loads associations to that entity from other entities), and if second-level caching is enabled for that entity, the following happens:
If an instance is already present in the first-level cache, it is returned from there
If an instance is not found in the first-level cache, and the corresponding instance state is cached in the second-level cache, then the data is fetched from there and an instance is assembled and returned
Otherwise, the necessary data are loaded from the database and an instance is assembled and returned
Once the instance is stored in the persistence context (first-level cache), it is returned from there in all subsequent calls within the same session until the session is closed or the instance is manually evicted from the persistence context. Also, the loaded instance state is stored in L2 cache if it was not there already.
Cache abstraction
Spring Framework provides an abstraction layer with set of annotations for caching support and can work together with various cache implementation like Redis, EhCache, Hazelcast, Infinispan and many more.
@Cacheable
@CachePut
@CacheEvict
@EnableCaching
@Caching
@CacheConfig
Hibernate Second-Level Cache
One of the advantages of database abstraction layers such as ORM (object-relational mapping) frameworks is their ability to transparently cache data retrieved from the underlying store. This helps eliminate database-access costs for frequently accessed data.
What Is a Second-Level Cache?
As most other fully-equipped ORM frameworks, Hibernate has the concept of first-level cache. It is a session scoped cache which ensures that each entity instance is loaded only once in the persistent context.
Once the session is closed, first-level cache is terminated as well. This is actually desirable, as it allows for concurrent sessions to work with entity instances in isolation from each other.
On the other hand, second-level cache is SessionFactory-scoped, meaning it is shared by all sessions created with the same session factory. When an entity instance is looked up by its id (either by application logic or by Hibernate internally, e.g. when it loads associations to that entity from other entities), and if second-level caching is enabled for that entity, the following happens:
Once the instance is stored in the persistence context (first-level cache), it is returned from there in all subsequent calls within the same session until the session is closed or the instance is manually evicted from the persistence context. Also, the loaded instance state is stored in L2 cache if it was not there already.
Spring Boot cache with Redis
Hibernate Second-Level Cache
spring-cache-tutorial