Ключевые проблемы кэширования с Jcache

Я использую JSR107 кеширование с Springboot. У меня есть следующий метод.

@CacheResult(cacheName = "books.byidAndCat")
public List<Book> getAllBooks(@CacheKey final String bookId, @CacheKey final BookCategory bookCat) {

return <<Make API calls and get actual books>>
}

Первый раз он выполняет реальные вызовы API, а второй раз загружает кеш без проблем. Я вижу следующую часть журнала.

Computed cache key SimpleKey [cb5bf774-24b4-41e5-b45c-2dd377493445,LT] for operation CacheResultOperation[CacheMethodDetails ...

Но проблема в том, что я хочу загрузить кеш, не совершая даже первого вызова API. Просто нужно заполнить кеш, как показано ниже.

String cacheKey  = SimpleKeyGenerator.generateKey(bookId, bookCategory).toString();     
        cacheManager.getCache("books.byidAndCat").put(cacheKey, deviceList);

Когда я проверяю, хэш-код кеширования одинаков в обоих случаях, но он делает вызовы API. Если хэш-код одинаков в обоих случаях, почему он выполняет вызовы API без учета кэша?

При отладке пружинных классов было установлено, что org.springframework.cache.interceptor.SimpleKeyGenerator используется с генерацией ключа кэша, даже если @CacheResult существует. РЕДАКТИРОВАТЬ и усилить вопрос:

Кроме того, если getAllBooks имеет перегруженные методы, а затем вызывает этот кэшированный метод с помощью отдельного перегруженного метода, в этом случае также не работает кэширование метода.

2 ответа

Решение

Как предложил @Henri, мы можем использовать кеш-данные. Но для этого нам нужны методы. Ниже мы можем обновить кеш, очень похожий на кеш-память,

// перегруженный метод доступен как id, так и cat.

List<Object> bookIdCatCache = new ArrayList<>();
    bookIdCatCache.add(bookId);
    bookIdCatCache.add(deviceCat);
    Object bookIdCatCacheKey  = SimpleKeyGenerator.generateKey(bookIdCatCache.toArray(new Object[bookIdCatCache.size()]));
    cacheManager.getCache("books.byidAndCat").put(bookIdCatCacheKey , bookListWithIdAndCat);

// перегружен только метод

List<Object> bookIdCache = new ArrayList<>();
        String nullKey          = null
        bookIdCache.add(bookId);
        bookIdCache.add(nullKey);
        Object bookIdCacheKey  = SimpleKeyGenerator.generateKey(bookIdCache.toArray(new Object[bookIdCache.size()]));
        cacheManager.getCache("books.byidAndCat").put(bookIdCacheKey , bookListWithId);

// Неправильно (Моя предыдущая реализация)

String cacheKey  = SimpleKeyGenerator.generateKey(bookId, bookCategory).toString();

// Правильно (это с весны)

Object cacheKey  = SimpleKeyGenerator.generateKey(bookIdCatCache.toArray(new Object[bookIdCatCache.size()]));

Я не эксперт по аннотациям JSR107 в контексте Spring. Вместо этого я использую аннотации Spring Cache.

При использовании JSR107 используется ключ GeneratedCacheKey, Так вот что вы должны поместить в свой кеш. Не toString() этого Обратите внимание, что SimpleKeyGenerator не возвращает GeneratedCacheKey, Возвращает SimpleKey который является ключом, используемым Spring при использовании его собственных аннотаций кэша вместо JSR-107. Для JSR-107 вам нужен SimpleGeneratedCacheKey,

Затем, если вы хотите предварительно загрузить кеш, просто позвоните getAllBooks прежде чем это нужно.

Если вы хотите предварительно загрузить кэш другим способом, @javax.cache.annotation.CachePut должен сделать свое дело. Смотрите его Javadoc для примера.

Другие вопросы по тегам