Reputation: 31
We have a MongoDb database that receives interactions from both a Springboot application and a Scala-based lambda using Circe serialization. When Circe serializes a sealed trait that is implemented by several classes, this is the outcome:
{
"ImplementationOfMySealedTrait": {
"aField": "some-data"
}
}
With Spring Data, serialization of a sealed interface has this result:
{
"aField": "some-data"
}
I am looking for a way to configure my Springboot application so that data is saved to MongoDb in the format that Circe uses.
I have attempted to use a custom Converter to convert my object to and from a Map. This works, but its pretty tedious:
@WritingConverter
class ProfileWriteConverter : Converter<MySealedInterface, Map<String, Any?>> {
override fun convert(source: MySealedInterface): Map<String, Any?> {
return mapOf(
source::class.java.simpleName to MapUtils.toMap(source)
)
}
}
@ReadingConverter
class ProfileReadConverter : Converter<Map<String, Any?>, MySealedInterface> {
override fun convert(source: Map<String, Any?>): MySealedInterface {
val implType = source.keys.first()
val impl = source[implType] as Map<String, Any?>
return when (profileType) {
"ImplOne" -> Json.deserialize(profile, ImplOne::class)
"ImplTwo" -> Json.deserialize(profile, ImplTwo::class)
else -> throw IllegalArgumentException("Unknown type: $implType")
}
}
}
Naturally, I could see us needing to use this conversion with other sealed interfaces. So ideally this configuration would be easily repeatable for other fields. This could get there, but I still am not particularly fond of it as a solution. I would love for this to be a simple configuration change, but alas, I am not seeing anything like that.
Upvotes: 0
Views: 26