Usage

Suppose that there’s a TaxService that calculates tax on Taxable items, with respect to some TaxType, and for a given LocalDate. To calculate tax it must run a database query and then perform some additional calculations.

Our original implementation is:

@DomainService
public class TaxService {
    public BigDecimal calculateTax(
            final Taxable t, final TaxType tt, final LocalDate d) {
        // query against DB using t, tt, d
        // further expensive calculations
    }
}

Suppose now that this service is called in a loop, for example iterating over a bunch of orders, where several of those orders are for the same taxable products, say. In this case the result of the calculation would always be the same for any given product.

We can therefore refactor the method to use the query cache as follows:

public class TaxService {
    public BigDecimal calculateTax(
            final Taxable t, final TaxType tt, final LocalDate d) {
        return queryResultsCache.execute(
            new Callable<BigDecimal>(){                         (1)
                public BigDecimal call() throws Exception {
                     // query against DB using t, tt, d
                     // further expensive calculations
                }
            },
            TaxService.class,                                   (2)
            "calculateTax",
            t, tt, d);
        }
}
1 the Callable is the original code
2 the remaining parameters in essence uniquely identify the method call.

This refactoring will be worthwhile provided that enough of the orders being processed reference the same taxable products. If however every order is for a different product, then no benefit will be gained from the refactoring.

The Scratchpad service is also intended for actions that are called many times, allowing arbitrary information to be shared between them.

Note that the scope of QueryResultsCache is for a single interaction, so is short-lived. If you want longer-lived caching, then you may be able to use Spring’s cache support, such as @Cacheable. For more details, check out the relevant Spring Boot and Spring Framework documentation on the topic.