2

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?

Eduardo
  • 6,900
  • 17
  • 77
  • 121

0 Answers0