You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I searched in the issues of databind and other modules used and found nothing similar.
I have confirmed that the problem only occurs when using Kotlin.
Describe the bug
Using a Kotlin inline-value-class a key in map breaks the Jackson serialization.
For example, it's not possible to read a map of type Map<Index, Int> where Index is a value class:
@JvmInline
value classIndex(valvalue:Int = 0)
// ↱ the `map` uses a value class `Index` as keydata classFooMapKey(valmap:MutableMap<Index, Int> = mutableMapOf())
Reading a JSON file with such a map fails:
val mapper = jacksonObjectMapper().registerKotlinModule()
val fooJson ="{ "map": { "1": 42 } }"val readValue = mapper.readValue<FooField>(fooJson) // ⚡`Cannot find a (Map) Key deserializer `
It fails during readValue(json) with the error:
Cannot find a (Map) Key deserializer for type [simple type, class de.itscope.catalog.pricelist.ParseValueClassTest$Index]
at [Source: REDACTED (`StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION` disabled); line: 1, column: 1]
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot find a (Map) Key deserializer for type [simple type, class de.itscope.catalog.pricelist.ParseValueClassTest$Index]
at [Source: REDACTED (`StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION` disabled); line: 1, column: 1]
at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:67)
It's does not belong to the input. It even fails if the map is empty:
{
"map" : { }
}
Using a value class as map-key, helps a lot to make map access type safe and improve the readability of code.
The other way around already works — Using the value class as value. So it's possible to save this class:
data class FooMapValue(val map : MutableMap<Int, Index> = mutableMapOf())
To Reproduce
@Test
funparseFooMapTest(){
val mapper = jacksonObjectMapper().registerKotlinModule()
val foo =FooMapKey().apply {
map[Index(1)] =42
}
val fooJson = mapper.writeValueAsString(foo)
val readValue = mapper.readValue<FooMapKey>(fooJson) // ⚡`Cannot find a (Map) Key deserializer `
assertEquals(foo, readValue)
}
Expected behavior
The mapper.readValue<FooMapKey>(fooJson) should read the JSON and deserialize into a FooMapKey.
Search before asking
Sorry, seems to be a duplicate of Cannot use value class as map key in 2.17 #777
Describe the bug
Using a Kotlin inline-value-class a key in map breaks the Jackson serialization.
For example, it's not possible to read a
map
of typeMap<Index, Int>
whereIndex
is a value class:Reading a JSON file with such a map fails:
It fails during
readValue(json)
with the error:It's does not belong to the input. It even fails if the map is empty:
{ "map" : { } }
Using a value class as map-key, helps a lot to make map access type safe and improve the readability of code.
The other way around already works — Using the value class as value. So it's possible to save this class:
To Reproduce
Expected behavior
The
mapper.readValue<FooMapKey>(fooJson)
should read the JSON and deserialize into aFooMapKey
.Versions
Kotlin:
2.0.0
Jackson-module-kotlin:
2.17.2
Jackson-databind:
2.17.2
Additional context
You can find a detailed test example for the problem here:
ParseValueClassMapTest.kt
The text was updated successfully, but these errors were encountered: