I have a model
data class SomeComplexObject<T>(val name: String, val value: T)
@Document("model")
data class SomeModel<T>(val id: String? = null, val map: Map<SomeComplexObject<T>, Int>)
Which I save to Mongo via the save
method of:
@Repository
interface SomeRepo<T>: MongoRepository<SomeModel<T>, String>
On it's own, this would throw a MappingException: Cannot use a complex object as a key value.
error so i'm trying to find a work around using Converters where my Converters change the Map
to a List
before persisting and back from List
-> Map
on Read.
@WritingConverter
class Map2ListConverter: Converter<Map<SomeComplexObject<*>, Int>, List<Pair<SomeComplexObject<*>, Int>>> {
override fun convert(domainModel: Map<SomeComplexObject<*>, Int>): List<Pair<SomeComplexObject<*>, Int>> {
return domainModel.map { (key, value) -> Pair(key, value) }
}
}
@ReadingConverter
class List2MapConverter: Converter<List<Pair<SomeComplexObject<*>, Int>>, Map<SomeComplexObject<*>, Int>> {
override fun convert(dbModel: List<Pair<SomeComplexObject<*>, Int>>): Map<SomeComplexObject<*>, Int> {
return dbModel.toMap()
}
}
Which I register with
@Bean
fun customConversions(): MongoCustomConversions {
val converters = ArrayList<Converter<*, *>>()
converters.add(Map2ListConverter())
converters.add(List2MapConverter())
return MongoCustomConversions(converters)
}
This however does not work & I get a CodecConfigurationException: Can't find a codec for class kotlin.Pair.
. It looks like spring tries to send a Document containing my Pair
class direct to Mongo which it understandably doesn't know what to do with.
Is there a way around this? Or do I need to admit defeat and just store my Maps as Sets everywhere?