Я хотел бы кешировать метод 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'
Хорошо, но я следил за учебником, на который я дал ссылку. Они использовали ключ key = "#newText + 1"
Учебник неправильный. Вы не можете иметь 2 метода, разные ключи chache и ожидать, что это сработает. Еще одна проблема заключается в том, что старые значения никогда не очищаются (если только время кэширования не истекло).
Итак, как добиться логики обновления одним методом? Мне кажется, что мне нужно два метода, я ошибаюсь?
Единственное, что вам нужно сделать, это убедиться, что ключ кеша одинаков для метода get и set. В настоящее время их нет.




Вы должны убедиться, что на значение, которое вы кэшируете в кеше, ссылается тот же ключ, что и при использовании кеша.
Например:
Допустим, вы кэшируете текст «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;
}
}
С чего бы это. Ключи для кеша различаются, поэтому
getTextникогда не видит кэшированный экземпляр.