-
Notifications
You must be signed in to change notification settings - Fork 74
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Kotlinx serialization favors sealed base serializer even when explicitly using subclass #310
Comments
Since Kotlin/kotlinx.serialization#1576 fix you can use the Workaround for now: use sealed class or define custom PolymorphicSerializer |
Sorry, I did not explain myself well. The issue is that I would expect [
{
"_id": { "$oid": "627e215005eed8558ea6f3c3" },
"___type": "Foo.FooA",
"x": 1
},
{
"_id": { "$oid": "627e215005eed8558ea6f3c5" },
"___type": "Foo.FooC",
"z": "a"
}
] and in a collection of only [
{
"_id": { "$oid": "627e215005eed8558ea6f3c3" },
"x": 1
},
{
"_id": { "$oid": "627e215005eed8558ea6f3c5" },
"x": 2
}
] I would say that a situation where I want both of these cases is unlikely, but in my case I wanted to have a separate collection for each of By allowing the serialization of As I previously mentioned I think the problem is that the implementation of KMongoSerializationRepository.getSerializer always uses the serializer of the superclass of |
Thank you for the explanation. Unfortunately the change would not be backward compatible. It would be also problematic for serialization without collection context: FooA(1).bson // -> do we use Foo or FooA serializer? May be it would be also counter-intuitive: database.getCollection<FooA>("foo").insert(FooA(2))
database.getCollection<Foo>("foo").find() // -> fail at runtime
database.getCollection<Foo>("foo2").insert(FooA(1))
database.getCollection<FooB>("foo2").find() // -> fail at runtime Though I agree with your remarks, the fix is not simple - it would need backward compatible flag & custom serializer for bson/json serialization - I think we are going to stay with your workaround :( |
I imagined it would not be simple to change this behavior, I mostly opened this issue in hope it would help if someone else incurs in the same problem. In case should we change the title back to something that better summarize the issue? In general the problem is with any sealed supertype (class or interface). Anyway thank you for this great tool! |
Than you for reporting the issue ! |
Problem description
When using kotlinx serialization if a type implements a
sealed interface
kmongo will try to serialize it using the interface serializer even if the compile-time type of the object is an implementation of the aforementioned interface.For example if i have the following types
and i attempt to insert an instance of
FooA
in a collection of onlyFooA
si get the error
Note that this does not happen if
Foo
is notsealed
, or ifFooA
is not the top-level document, as in the following exampleCause
The issue seems to be in the implementation of KMongoSerializationRepository.getSerializer which is used to get the serializer when inserting documents and favors the superclass serializer.
Workaround
Explicitly specifying the serializer of the various
Foo
implementations like in the following example solves the issueAdding a module that specifies contextual serializers for the implementations of
Foo
also works.The text was updated successfully, but these errors were encountered: