Caching using Spring Boot with Example – Cache:

Caching and its Uses:

Caching is the process of storing the data at a temporary location. The main purpose of it is reduce the number of communications with the database.

In an application it is always best to reduce number of database communications to improve the performance of the application. Certain GET calls will mostly return the same results irrespective of number of times its been queried with the database.

So for querying every time to get the same result, we can store them in the cache and whenever the API is called we can retrieve the data from the Cache.

The cache also has its disadvantage, if you build a larger cache then the system will not execute the cache with the same speed as of smaller cache.

There are various caching techniques available,

  • Generic
  • JCache (JSR-107) (EhCache 3, Hazelcast, Infinispan, and others)
  • EhCache 2.x
  • Hazelcast
  • Infinispan
  • Couchbase
  • Redis
  • Caffeine
  • Simple

Refer here.

In this example let use look at a simple generic cache mechanism.

We are going to use the below annotations in our example,

  • @EnableCaching
  • @Cacheable
  • @CachePut
  • @CacheEvict


We need to include this annotation in the SpringBootApplication to notify the spring boot application that caching has been included.


This is used to cache the values


This is also used to cache the values.

But there is a difference between @Cacheable and @CachePut

Cacheable will not execute the method, will return when the method is calledCacheput will execute the method and then will return the cache.
Cacheable vs Cacheput


When you have to remove the cache we can use cacheEvict

Now let us see an example,


<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="" xmlns:xsi=""
		<relativePath/> <!-- lookup parent from repository -->
	<description>Database Demo</description>
		<!-- -->




Let us create a model class Employee,

package com.database.demo.model;

import javax.persistence.*;

@Table(name = "Employee")
public class Employee {

    private int id;

    private String name;
    private String empId;

    public int getId() {
        return id;

    public void setId(int id) { = id;

    public String getName() {
        return name;

    public void setName(String name) { = name;

    public String getEmpId() {
        return empId;

    public void setEmpId(String empId) {
        this.empId = empId;

Now let us create an Repository,

package com.database.demo.repository;

import com.database.demo.model.Employee;
import org.springframework.stereotype.Repository;

public interface EmployeeDAO extends JpaRepository<Employee, Integer> {


Service class,

package com.database.demo.service;

import com.database.demo.model.Employee;
import com.database.demo.repository.EmployeeDAO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.stereotype.Service;
import org.springframework.cache.annotation.Cacheable;

public class EmployeeService {

    private EmployeeDAO eDao;

    public Employee getEmployeeById(int id) {
        return eDao.findById(id).orElse(null);

    public Employee saveEmployee(Employee employee) {

    public Employee getEvictEmployee(int id) {
        return eDao.findById(id).orElse(null);

    public Employee getPutEmployee(int id) {
        return eDao.findById(id).orElse(null);

Now let us create a controller,

package com.database.demo.controller;

import com.database.demo.model.Employee;
import com.database.demo.service.EmployeeService;
import org.springframework.web.bind.annotation.*;

import javax.transaction.Transactional;

public class EmployeeController {

    private EmployeeService service;

    public EmployeeController(EmployeeService service) {
        this.service = service;

    @PostMapping(value = "/saveEmployee")
    public Employee save(@RequestBody Employee employee) {
        return service.saveEmployee(employee);

    @GetMapping(value = "/getEmployee/{id}")
    public Employee getEmployee(@PathVariable("id") Integer id) {

        return service.getEmployeeById(id);

    @GetMapping(value = "/getPutEmployee/{id}")
    public Employee getPutEmployee(@PathVariable("id") Integer id) {

        return service.getPutEmployee(id);

    @GetMapping(value = "/getEvictEmployee/{id}")
    public Employee getEvictEmployee(@PathVariable("id") Integer id) {

        return service.getEvictEmployee(id);

    public Employee updateEmployee(@RequestBody Employee employee){
        return service.saveEmployee(employee);


In the above example we have used @Cacheable Annotation with the value “employee”.

When we execute the method first time it will get the data from database and further calling the same API, the data will be retrieved from the cache and not from database.



package com.database.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.cache.annotation.EnableCaching;

public class DemoApplication {

	public static void main(String[] args) {, args);


Now let us run our application and test it,

Step 1: Save the employee,

Save Employee

Step 2:

get the employee by ID: 1,


Step 3:

Now let us see our log file whether the query has been logged,

From the logs – Query has been logged – Means DB call is made

Step 4:

Step 3, database call is made and as per our code it has to be cached now..Now when we try to getById again this time there should not be any database call.

Then our cache is working fine.

Step 5:

Now update the employee record,


Step 6:

Now when we try the getById, we will still get empId as 001. Why?

Cause, Cacheable will not execute the method and as per the cache – it will still have the old record!

Step 7:

Now let us try cachePut API, it will execute the method and will give us the updated result,


Step 8:

Now let us try to remove our cache with evict API,

Evict Employee

Step 9:

After evict, when we try to getById again, it will fetch from database –> we can validate from Query.

Step 9

Thats it about the generic cache!

Code can be downloaded here

By Sri

Leave a Reply

Your email address will not be published. Required fields are marked *