I've implemented basic set up of Caffeine cache in Spring Boot app. Below you will find configuration and service method annotated with @Cachable
. Unfortunately every call for this method generates database query and new input to cache (with same key):
Debug result with cache content
@Cacheable(cacheNames = {"pic"})
public PictureModel loadPictureById(String id) {
var loadedInstance = pictureRepo.findById(id).orElseThrow(() -> new CustomNotFoundException(PictureModel.class));
loadedInstance.setBody(pictureCompressor.decompressBytes(loadedInstance.getBody()));
return loadedInstance;
}
Configuration:
@EnableCaching
@Configuration
public class CaffeineConfig {
@Bean
public CacheManager cacheManager() {
CaffeineCacheManager cacheManager = new CaffeineCacheManager("pic");
cacheManager.setCaffeine(caffeineCacheBuilder());
return cacheManager;
}
Caffeine <Object, Object> caffeineCacheBuilder() {
return Caffeine.newBuilder()
.initialCapacity(100)
.maximumSize(500)
.expireAfterAccess(10, TimeUnit.MINUTES)
.weakKeys()
.recordStats();
}
}
Database queries after three hits:
Hibernate:
select
picturemod0_.id as id1_10_0_,
picturemod0_.account_id as account_5_10_0_,
picturemod0_.body as body2_10_0_,
picturemod0_.name as name3_10_0_,
picturemod0_.public_platform_id as public_p6_10_0_,
picturemod0_.service_type_id as service_7_10_0_,
picturemod0_.type as type4_10_0_
from
image picturemod0_
where
picturemod0_.id=?
Hibernate:
select
picturemod0_.id as id1_10_0_,
picturemod0_.account_id as account_5_10_0_,
picturemod0_.body as body2_10_0_,
picturemod0_.name as name3_10_0_,
picturemod0_.public_platform_id as public_p6_10_0_,
picturemod0_.service_type_id as service_7_10_0_,
picturemod0_.type as type4_10_0_
from
image picturemod0_
where
picturemod0_.id=?
Hibernate:
select
picturemod0_.id as id1_10_0_,
picturemod0_.account_id as account_5_10_0_,
picturemod0_.body as body2_10_0_,
picturemod0_.name as name3_10_0_,
picturemod0_.public_platform_id as public_p6_10_0_,
picturemod0_.service_type_id as service_7_10_0_,
picturemod0_.type as type4_10_0_
from
image picturemod0_
where
picturemod0_.id=?
I would like to achieve one database query and other hits to be served by cache.
Remove weakKeys()
from your CaffeineConfig
.
From weakKeys()
documentation,
Warning: when this method is used, the resulting cache will use identity (==) comparison to determine equality of keys.
In your config , you are computing keys as Object but weakKeys()
is comparing them with ==
, so keys are matched as not eqaul and cache miss is happening.