Spring cache, force to set the return type

I'm trying to implement org.springframework.cache.Cache The cached value is stored as JSON in a SQL database. In the Cache interface, there are multiple get methods.

ValueWrapper get(Object key); <T> T get(Object key, @Nullable Class<T> type); <T> T get(Object key, Callable<T> valueLoader); 

This is the first one that is used (without type or any generic information). The problem is that since I save the value as JSON, I'd like to have the return value of the cached methods to help deserialize it.

How can I force spring to use the method <T> T get(Object key, @Nullable Class<T> type); when using the @Cacheable annotation ?

My cache implementation (kotlin) :

class SqlCache( private val name: String, private val expiration: Duration, private val cacheRepository: CacheRepository, ): Cache { private val isoObjectMapper = ObjectMapper() .registerModule(KotlinModule()) .registerModule(JavaTimeModule()) .disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS) .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) override fun getName(): String { return name } override fun getNativeCache(): Any { return cacheRepository } // The method called by spring ! override fun get(key: Any): Cache.ValueWrapper? { val cache = cacheRepository.find(name = name, key = key.toString()) ?: return null val value = isoObjectMapper.readValue(cache.value, UserModel::class) return SimpleValueWrapper(value) } override fun <T : Any?> get(key: Any, type: Class<T>?): T? { val cache = cacheRepository.find(name = name, key = key.toString()) ?: return null return isoObjectMapper.readValue(cache.value, type) } override fun <T : Any?> get(key: Any, valueLoader: Callable<T>): T? { return null } override fun put(key: Any, value: Any?) { cacheRepository.put( name = name, key = key.toString(), value = value, expiration = expiration, ) } override fun evict(key: Any) { cacheRepository.delete( name = name, key = key.toString(), ) } override fun clear() { } } 

Exemple of cache usage :

interface UserClientAdapter { @Cacheable(value = ["user-cache"], key = "#id") fun getUser(id: UUID): UserModel } 

So, in this last method, the user is well stored as a JSON string in the database. But when we try to get back the cache. This is the method ValueWrapper get(Object key); that is called. So I don't know the expected return type of the method.

1 Answer

You should refer to the RedisCache implementation class. extends AbstractValueAdaptingCache Implement the lookup method Write your deserialization method in the lookup method

protected Object lookup(Object key) { byte[] value = this.cacheWriter.get(this.name, this.createAndConvertCacheKey(key)); return value == null ? null : this.deserializeCacheValue(value); } 

If you still can't return your results

Then you need to debug CacheAspectSupport.java execute method,

which handles the hit Cache.ValueWrapper

12

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

You Might Also Like