I have one spring boot application
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3.4.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.example</groupId> <artifactId>cachedemo</artifactId> <version>0.0.1-SNAPSHOT</version> <name>cachedemo</name> <description>Demo project for Spring Boot cache</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-cache</artifactId> <!-- <version>2.2.6.RELEASE</version> --> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
CacheDemoAllpication.java
package com.example.cachedemo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCaching; @SpringBootApplication @EnableCaching public class CachedemoApplication { public static void main(String[] args) { SpringApplication.run(CachedemoApplication.class, args); } }
Controller
package com.example.cachedemo.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import com.example.cachedemo.model.Book; import com.example.cachedemo.service.LibraryService; @Controller public class HomeController { @Autowired private LibraryService service; @RequestMapping("/get") public String getBooks(@RequestParam Integer id) { Book book = service.getBook(id); System.out.println(book); return book.toString(); } }
Service
package com.example.cachedemo.service; import java.util.HashMap; import java.util.Map; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; import com.example.cachedemo.model.Book; @Service public class LibraryService { // @Cacheable(value = "bookCache") public Book getBook(Integer id) { System.out.println("*******************************************Method called getBook()************************************"); Map<Integer,Book> bookMap = getBookMap(); return bookMap.get(id); } @Cacheable(value = "booksCache", key="#root.methodName") private Map<Integer,Book> getBookMap() { Book b3 = new Book(2,"Peace","Arif"); Book b2 = new Book(3,"Mumbai City","Shiv Shankar"); Book b1 = new Book(1,"Test","Sunny"); Map<Integer,Book> bookMap = new HashMap<Integer, Book>(); bookMap.put(1, b1); bookMap.put(2, b2); bookMap.put(3, b3); System.out.println("*******************************************Method called getBookMap()************************************"); return bookMap; } }
In the service class getBookMap() return a Map and I want spring to cache that. For subsequent requests it should return that map from cache. But with current setup It’s not caching anything and getBookMap() method is being executed every time. My first suspect was spring-boot-starter-cache version, but that’s not the case. The behavior is same with latest version as well.
I have tried with/without key=”#root.methodName” but the result is same.
Whereas if I cache method getBook(Integer id) it works just fine which gets me into thinking that no parameter methods are behaving differently.
Advertisement
Answer
- @Cacheable won’t work for private methods, make your method public
- You can’t call a cacheable method from within the same class. I mean put your Cacheable method into another class and make it public. Call the method from another class. Then it’ll work