I have several Kotlin data classes that implement this TypeAlias interface:
import com.fasterxml.jackson.annotation.JsonValue;
public interface TypeAlias<T> {
@JsonValue
T getValue();
}
Previously, I'd been using an earlier version of Jackson and they deserialized fine. But now I'm using 2.9.9.
One class that fails to deserialize:
data class UserId(@NotNull private val value: EntityId) : TypeAlias<EntityId> {
@JsonCreator(mode = JsonCreator.Mode.DELEGATING)
constructor(value: String) : this(EntityId(value))
override fun getValue() = value
}
Test for it:
@Test
fun `Deserialization test`() {
val userIdString = "\"aaaaaaaaaaaaaaaaaaaaaa\""
mapper.readValue(userIdString, UserId::class.java)
}
This test blows up with:
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `UserId` (no Creators, like default construct, exist): no String-argument constructor/factory method to deserialize from String value ('aaaaaaaaaaaaaaaaaaaaaa')
My mapper does have the KotlinModule registered.
Note that UserId does have a JsonCreator on its secondary String constructor. The behavior makes me think that the interface is causing Jackson to not see the @JsonCreator annotation. What am I missing here?
You need a valid Jackson config. Take a look at this example
@Configuration
class JacksonConfig {
@Bean
fun objectMapper(): ObjectMapper {
val objectMapper = ObjectMapper()
val jdk8Module = Jdk8Module().configureAbsentsAsNulls(true)
objectMapper.registerModule(jdk8Module)
objectMapper.registerModule(JavaTimeModule())
// ... your customizations
objectMapper.registerKotlinModule()
return objectMapper
}
}
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