I am mapping a class hierarchy to a database json ...
# jackson-kotlin
p
I am mapping a class hierarchy to a database json field (spring boot, kotlin) Should I enumerate every
@JsonSubTypes
by hand, of is there a convenient solution to use the class name? So how to avoid
Copy code
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
@JsonSubTypes(
        JsonSubTypes.Type(value=MyState1::class, name = "MyState1"),
// ...
// ...
        JsonSubTypes.Type(value= MyState99::class, name = "MyState99")
)
abstract class AbstractState
Btw I don't need the class at all, I am just logging to a jsonb field, and will query it directly from db. So say, I have this hierarchy:
Copy code
abstract class AbstractState

data class MyState(val text: String)
and all my wish is to put
Copy code
{
  "text": "the text value"
}
to a jsonb field.
t
you can consider custom ser/deser, they offer you more flexibility for this type of use cases. for instance
Copy code
val objectMapper: ObjectMapper by lazy {
  JsonMapper.builder()
    .findAndAddModules()
    .addModules(
      SimpleModule()
        .addDesers<Any>(CustomAbstractStateDeerializer())
        .addSers(CustomAbstractStateSerializer())
    .build()
}

private fun <T> SimpleModule.addDesers(vararg desers: JsonDeserializer<*>) = apply {
  desers.forEach { this.addDeserializer(it.handledType() as Class<T>, it as JsonDeserializer<out T>) }
}

private fun SimpleModule.addSers(vararg sers: JsonSerializer<*>) = apply {
  sers.forEach { this.addSerializer(it) }
}

class CustomAbstractStateDeserializer : StdDeserializer<Calculation>(AbstractState::class.java) {
  override fun deserialize(p: JsonParser, ctxt: DeserializationContext): AbstractState {
    // play around here to convert from json to code, this code sample will NOT work
    return p.codec.readValue(p, AbstractState::class.java)
  }
}

class CustomAbstractStateSerializer : StdSerializer<AbstractState>(AbstractState::class.java) {
  override fun serialize(value: AbstractState, gen: JsonGenerator, provider: SerializerProvider) {
    gen.writeStartObject()
    //play around here to generate you custom json, eg:
    when (value) {
      is MyState -> gen.writeObjectField("text", value.text)
    }
    gen.writeEndObject()
  }
}
p
ITMT I solved it with a simple
objectMapper.writeValueAsString(myAbstractState)