@CachePut не обновляет кеш

Я хотел бы кешировать метод getText и обновлять кеш на setText. На данный момент кеширование по методу getText работает, но я не могу обновить значение. Код ниже основан на руководстве от Хейзелкаст.

@Service
public class SlowService {

    String text = "Initial value";

    @Cacheable("text")
    public String getText() {
        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return text;
    }

    @CachePut(value = "text", key = "#newText + 1")
    public String setText(String newText) {
        text = newText;
        return text;
    }
}

Как улучшить код выше, чтобы аннотация @CachePut работала?

Обновлено: Пробовал добавлять те же ключи:

@Cacheable(value = "text", key = "#someKey")
    public String getText() {
        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return text;
    }

    @CachePut(key = "#someKey")
    public String setText(String newText) {
        text = newText;
        return text;
    }

Но получаю:

java.lang.IllegalArgumentException: Null key returned for cache operation (maybe you are using named params on classes without debug info?) Builder[public java.lang.String com.example.demo.SlowService.getText()] caches=[text] | key='#someKey' | keyGenerator='' | cacheManager='' | cacheResolver='' | condition='' | unless='' | sync='false'

С чего бы это. Ключи для кеша различаются, поэтому getText никогда не видит кэшированный экземпляр.

M. Deinum 11.03.2019 10:25

Хорошо, но я следил за учебником, на который я дал ссылку. Они использовали ключ key = "#newText + 1"

Bartek 11.03.2019 10:32

Учебник неправильный. Вы не можете иметь 2 метода, разные ключи chache и ожидать, что это сработает. Еще одна проблема заключается в том, что старые значения никогда не очищаются (если только время кэширования не истекло).

M. Deinum 11.03.2019 10:33

Итак, как добиться логики обновления одним методом? Мне кажется, что мне нужно два метода, я ошибаюсь?

Bartek 11.03.2019 10:40

Единственное, что вам нужно сделать, это убедиться, что ключ кеша одинаков для метода get и set. В настоящее время их нет.

M. Deinum 11.03.2019 10:41
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Версия Java на основе версии загрузки
Версия Java на основе версии загрузки
Если вы зайдете на официальный сайт Spring Boot , там представлен start.spring.io , который упрощает создание проектов Spring Boot, как показано ниже.
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
0
5
2 820
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вы должны убедиться, что на значение, которое вы кэшируете в кеше, ссылается тот же ключ, что и при использовании кеша.

Например:

Допустим, вы кэшируете текст «Hello world» с ключом «hw». Ваш кеш будет содержать ключ «hw» со значением «Hello world».

Теперь предположим, что вы хотите обновить значение с помощью клавиши «hw» на другой текст. Для этого вам нужно убедиться, что ключ, который вы передаете, совпадает с тем, который вы передали для кэширования этого экземпляра, который в этом случае будет «hw».

Таким образом, ключ «hw» будет содержать обновленное значение.

@Cacheable(value = "text", key = "hw")
public String getText() {
    try {
        TimeUnit.SECONDS.sleep(2);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    return text;
}

@CachePut(key = "hw")
public String setText(String newText) {
    text = newText;
    return text;
}
Ответ принят как подходящий

Проблема заключалась в именовании ключей, имя строки должно быть заключено в ', намекать. Ниже рабочий код.

@Service
public class SlowService {

    String text = "Initial value";

    @Cacheable(value = "text", key = "'someKey'")
    public String getText() {
        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return text;
    }

    @CachePut(value = "text", key = "'someKey'")
    public String setText(String newText) {
        text = newText;
        return text;
    }
}

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