I have a Spring boot app written in Kotlin where I would like to enable caching in Redis. I'd like to have the objects stored as serialized JSON and ideally don't want to have to register each type that could be potentially cached. I have some configuration that mostly works, with a big caveat.
@Bean
fun redisCacheConfiguration(): RedisCacheConfiguration {
val objectMapper =
ObjectMapper()
.registerModule(KotlinModule())
.registerModule(JavaTimeModule())
.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY)
val serializer = GenericJackson2JsonRedisSerializer(objectMapper)
return RedisCacheConfiguration
.defaultCacheConfig()
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(serializer))
}
I'm having a little trouble understanding the different values for DefaultTyping
but NON_FINAL
seems to be the most expansive. However, since objects in Kotlin are final by default, this only works for objects flagged as "open". Ideally I'd like to avoid having to "open" objects just so they can be cached.
Is there some other way I can make this work?
I had the same problem. You should use "open" classes. But this will not help you with data classes, because you cannot make them "open".
There is a plugin called "all-open" where you can define annotations. If you use these annotations classes become "open", even data classes.
spring-kotlin plugin uses "all-open" plugin under the hood, so spring annotations like @Service, @Component etc. make classes open for AOP, because proxying requires you to inherit from classes.
If you use spring-kotlin plugin, there is nice annotation that makes sense for you problem, it is used in Spring Cache, its name is @Cacheable. If you use @Cacheable on your classes, they will become open and save their type-info to json (ex: {@class: "com.example.MyClass", ...}) when you include this code:
val objectMapper =
ObjectMapper()
.registerModule(KotlinModule())
.registerModule(JavaTimeModule())
.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY)
val serializer = GenericJackson2JsonRedisSerializer(objectMapper)
More details: https://kotlinlang.org/docs/reference/compiler-plugins.html
Shortly: You don't have to do anything except adding @Cacheable annotation to the classes you want, and it fits by sense also IMO.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With