Enabling Request-Scoped Caching on a Repository Method
Enabling Request-Scoped Caching on a Repository Method
@CacheResult public Customer getCustomer(CustomerId customerId){ ... }
In most cases, the @CacheResult annotation is the only thing needed to enable caching.
Cache Key Variants
Repository methods may need to retrieve the same domain objects by different keys, as different resources provide different information on the same object. For example, a resource which knows about a user's default cart may not know about that cart's GUID, whereas a resource accessed via a URI that retrieves a specific cart does.
If you must retrieve the same domain object with via different unique identifiers, enable cache key variants to avoid a decrease in performance.
How Cache Key Variants Work
Domain objects may have multiple key variants by which they can be retrieved. In general, any uniquely identifying field of a domain object can be used as a cache key.
Cache key variants allow the domain object to register itself with a CacheKeyManager class, tracking all possible values that useable as a cache key. This allows Cortex to identify when an object can be retrieved from the cache, even if it is called by a different key than it was initially cached under.
class Customer { String storeCode, userId; String guid; }
A repository class has the following cached methods, both of which retrieve the same domain object by different unique identifiers in their method signatures:
@CacheResult public Customer findCustomerByUserId(String storeCode, String userId) { ... } @CacheResult public Customer findCustomerByGuid(String guid) { ... }
In this example, the first method, findCustomerByUserId(), caches the domain object. The second method, findCustomerByGuid(), utilizes cache key variants to retrieve the domain object cached by findCustomerByUserId(), rather than retrieving the object again from Commerce Engine.
Implementing Cache Key Variants
Cache key variants are not implemented by default. To implement cache key variants on a domain object:
- Implement the CacheKeyVariants interface
- Within this implementation, register the key variants of the domain object you wish to cache.
- Register the interface implementation with the CacheKeyManager class.
Key variants have to be unique otherwise inconsistencies might occur.
@Singleton @Named("customerCacheKeyVariants") public final class CustomerCacheKeyVariants implements CacheKeyVariants<Customer> { @Override public Collection<Object[]> get(final Customer customer) { return Arrays.asList( new Object[] { customer.getGuid() }, new Object[] { customer.getStoreCode(), customer.getUserId() } ); } @Override public Class<Customer> getType() { return Customer.class; } }}
Best Practices
Avoid Method Signature Collision
@CacheResult(uniqueIdentifier = "default-customer-address") public Address getDefaultCustomerAddress(CustomerId customerId) { ... } @CacheResult(uniqueIdentifier = "shipping-address") public Address getShippingAddress(CustomerId customerId) { ... }