javaspring-bootspring-data-jpaspring-cache

How to Cache Pageable in Spring Boot?


I am trying to cache Pageable in Spring Boot. How do I handle caching for each page passed in pageable object?

@Service
public class MarketServiceImpl implements MarketService {

@Autowired
MarketDao marketDao;

@Cacheable(value = "marketData" key=?)
public Page<StockMarkets>  findAllMarket(Pageable pageable){
    return marketDao.findAll(pageable);
 }
}

Solution

  • Your question here is somewhat ambiguous, at least to me.

    You said, "I am trying to cache Pageable in Spring Boot..."

    And then go onto show the code snippet with an @Cacheable method signature:

    @Cacheable(value = "marketData" key=?)
    public Page<StockMarkets>  findAllMarket(Pageable pageable){
        return marketDao.findAll(pageable);
    }
    

    With the key attribute of the @Cacheable annotation declared on your findAllMarket(..) service method set to ?, I assume you are not sure what the value of this key attribute should be?

    Well, first of all, and technically, you do not even need to set the key attribute since Spring Framework's caching infrastructure will, by DEFAULT, "derive" a key from the @Cacheable method signature (i.e. findAllMarket(:Pageable)), using the arguments passed to the method parameters of the @Cacheable method (again, findAllMarket(:Pageable)), and in this case, that means the Pageable (request) object.

    TIP: See Spring Framework's Cache Abstraction documentation on "Default key Generation", for more details.

    TIP: You can also "customize" the key generation as well, see here.

    So, Spring's caching infrastructure will use the Pageable parameter argument as the "key" in the cache entry, mapped to the Page<StockMarkets> object (that will be the cache entry value) returned by the method.

    So, the outcome of the findAllMarket(:Pageable) method call will result in a cache entry stored in your "marketData" cache similar to:

    marketData cache

    KEY           | VALUE
    --------------|------------------------
    Pageable@1234 | Page<StockMarkets>@9876
    

    This will be true for every Pageable (request) object passed to the @Cacheable findAllMarket(..) service method, unless the Pageable object is logically and semantically "equal", then the "cached" entry (i.e. Page<StockMarkets>) will be returned.

    Fortunately, Spring Data's Pageable interface implementations (e.g. PageRequest; see Javadoc) do override the Object equals and hashCode methods, so they are acceptable for use as "cache keys".

    Keep in mind that any object used as a cache key should most definitely override the java.lang.Object, equals(:Object) and hashCode() methods, always. Caches are just glorified Map (data structures) after all.

    Hope this makes sense.

    Good luck!