Reputation: 353
I'm trying to update values in spring cache, however @CachePut does not replace actual value, but put another value with the same key:
Cachename: noTimeCache:
1.Why?
My cache service:
@CachePut(value = "noTimeCache", key = "#setting.getSetting().name()")
public String updateGlobalCacheValue(GlobalSettings setting) {
System.out.println("Setting: " + setting.getSetting().name() + ", val: " + setting.getValue());
return setting.getValue();
}
I know it's looks funny but i need to work with jpa repositories. Maybe someone have better solution.
2.Why can't I use function argument as @Cacheable key like this?
@Cacheable(value = "noTimeCache", key = "#setting.name()", unless = "#result == null")
@Query("SELECT gs.value FROM GlobalSettings gs WHERE gs.setting = ?1")
String getGlobalSettingValue(Settings setting);
It tells me setting is null.
3.Is the way to override @Repositository interface methods, for example save() to add annotation @Cacheable to them?
Upvotes: 4
Views: 18902
Reputation: 353
Thanks for answers. It helps me solve problems.
@CachePut replace values, but there was a problem in keys. I use something like this:
@Cacheable(value = "globalSettings", unless = "#result == null")
@Query("SELECT gs.value FROM GlobalSettings gs WHERE gs.setting = ?1")
String getGlobalSettingValue(Settings setting);
Settings is enum and key for default is enum name, for example SYSTEM_STATUS.
and this:
@Cacheable(value = "globalSettings", key = "#setting.name()")
public String getGlobalSettingEnumValue(Settings setting) {
return Settings.valueOf(setting.name()).getDefaultValue();
}
will also save key as STSYEM_STATUS.
Key's was the same but cache interprets this like 2 different cache values, I don't know why.
U can't use variable name in repository class like #setting, it must be argument index like #p0, probably beacause of spring data use his own proxy classes.
This solve all my problems and now cache work properly.
Upvotes: 2
Reputation: 1687
1-@CachePut does not replace actual value, but put another value :delete key = "#setting.name" in that way keygenarator will use the hashcode of GlobalSettings(verify if the hashcode is implemented correctly)and also verify if the name of the cache "noTimeCache" is not specified to other methods.
2-see this link http://docs.spring.io/spring/docs/current/spring-framework-reference/html/cache.html if the "setting" parameter is an attribute in GlobalSettings you can change the SpEL expression #setting.getSetting().name() to #setting.setting.name
3-You can do the following if you are using java 6 (no idea if this is possible with java 7 or 8 ) :
public interface GlobalSettingsRepository extends JpaRepository<GlobalSettings, Long>{
@Override
@CacheEvict(value = {"noTimeCache"}, allEntries = true)
GlobalSettings save(GlobalSettings globalSettings);
}
Upvotes: 1