diff --git a/bson-kotlin/src/main/kotlin/org/bson/codecs/kotlin/DataClassCodec.kt b/bson-kotlin/src/main/kotlin/org/bson/codecs/kotlin/DataClassCodec.kt index 412a0483231..5431a765d48 100644 --- a/bson-kotlin/src/main/kotlin/org/bson/codecs/kotlin/DataClassCodec.kt +++ b/bson-kotlin/src/main/kotlin/org/bson/codecs/kotlin/DataClassCodec.kt @@ -18,10 +18,10 @@ package org.bson.codecs.kotlin import java.lang.reflect.ParameterizedType import java.lang.reflect.Type import kotlin.reflect.KClass +import kotlin.reflect.KClassifier import kotlin.reflect.KFunction import kotlin.reflect.KParameter import kotlin.reflect.KProperty1 -import kotlin.reflect.KType import kotlin.reflect.KTypeParameter import kotlin.reflect.KTypeProjection import kotlin.reflect.full.createType @@ -142,7 +142,9 @@ internal data class DataClassCodec( val primaryConstructor = kClass.primaryConstructor ?: throw CodecConfigurationException("No primary constructor for $kClass") val typeMap = - types.mapIndexed { i, k -> primaryConstructor.typeParameters[i].createType() to k }.toMap() + types + .mapIndexed { i, k -> primaryConstructor.typeParameters[i].createType().classifier!! to k } + .toMap() val propertyModels = primaryConstructor.parameters.map { kParameter -> @@ -193,7 +195,7 @@ internal data class DataClassCodec( @Suppress("UNCHECKED_CAST") private fun getCodec( kParameter: KParameter, - typeMap: Map, + typeMap: Map, codecRegistry: CodecRegistry ): Codec { return when (kParameter.type.classifier) { @@ -201,10 +203,12 @@ internal data class DataClassCodec( codecRegistry.getCodec( kParameter, (kParameter.type.classifier as KClass).javaObjectType, - kParameter.type.arguments.mapNotNull { typeMap[it.type] ?: computeJavaType(it) }.toList()) + kParameter.type.arguments + .mapNotNull { typeMap[it.type?.classifier] ?: computeJavaType(it) } + .toList()) } is KTypeParameter -> { - when (val pType = typeMap[kParameter.type] ?: kParameter.type.javaType) { + when (val pType = typeMap[kParameter.type.classifier] ?: kParameter.type.javaType) { is Class<*> -> codecRegistry.getCodec(kParameter, (pType as Class).kotlin.javaObjectType, emptyList()) is ParameterizedType -> diff --git a/bson-kotlin/src/test/kotlin/org/bson/codecs/kotlin/DataClassCodecTest.kt b/bson-kotlin/src/test/kotlin/org/bson/codecs/kotlin/DataClassCodecTest.kt index d2dbfc580cc..40abc3a9cfa 100644 --- a/bson-kotlin/src/test/kotlin/org/bson/codecs/kotlin/DataClassCodecTest.kt +++ b/bson-kotlin/src/test/kotlin/org/bson/codecs/kotlin/DataClassCodecTest.kt @@ -249,7 +249,7 @@ class DataClassCodecTest { |"nestedParameterized": { | "parameterizedDataClass": | {"number": 4.2, "string": "myString", "parameterizedList": [{"name": "embedded1"}]}, - | "other": "myOtherString" + | "other": "myOtherString", "optionalOther": "myOptionalOtherString" | } |}""" .trimMargin() @@ -257,7 +257,9 @@ class DataClassCodecTest { DataClassWithNestedParameterizedDataClass( "myId", DataClassWithNestedParameterized( - DataClassParameterized(4.2, "myString", listOf(DataClassEmbedded("embedded1"))), "myOtherString")) + DataClassParameterized(4.2, "myString", listOf(DataClassEmbedded("embedded1"))), + "myOtherString", + "myOptionalOtherString")) assertRoundTrips(expected, dataClass) } diff --git a/bson-kotlin/src/test/kotlin/org/bson/codecs/kotlin/samples/DataClasses.kt b/bson-kotlin/src/test/kotlin/org/bson/codecs/kotlin/samples/DataClasses.kt index a320470cf23..5bc6e768ed8 100644 --- a/bson-kotlin/src/test/kotlin/org/bson/codecs/kotlin/samples/DataClasses.kt +++ b/bson-kotlin/src/test/kotlin/org/bson/codecs/kotlin/samples/DataClasses.kt @@ -89,7 +89,8 @@ data class DataClassWithNestedParameterizedDataClass( data class DataClassWithNestedParameterized( val parameterizedDataClass: DataClassParameterized, - val other: B + val other: B, + val optionalOther: B? ) data class DataClassWithPair(val pair: Pair)