Skip to content
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

Fix deserialization of un-annotated Option[Trait] fields #383

Closed
wants to merge 1 commit into from

Conversation

ypoluektovich
Copy link

See issue #382.

I'm using valueTypeDeserializer.get and then wrap the result in Some, instead of just using map, so that it'd crash if there's no valueTypeDeserializer. I don't know if that situation is possible, and there are no failing tests.

@ypoluektovich
Copy link
Author

Warning: this breaks deserialization of old JSON strings in which options were wrapped in a list.

@nbauernfeind
Copy link
Member

Can you elaborate further on your warning? What did the old serialization look like? What does the new serialization look like?

@ypoluektovich
Copy link
Author

Options used to be serialized like this, at least in 2.8.9 (and assuming the ObjectMapper configuration I cited in #382):

[
  "scala.Option",
  {
    "_t": "optional_object_class_name",
    "other_fields_of_optional_object": "..."
  }
]

However, now the OptionSerializer just writes the inner object without any wrapping (again, see the example in the first comment of #382).
Without this patch, OptionDeserializer can deserialize old-style Options, but not new-style ones. With the patch, it's the other way around.
I can try looking for ways to support both, but no promises about when, or whether it's even possible. If it proves impossible, my opinion is that the library should support configuration-less deserialization of the results of configuration-less serialization of the same version of the library.

@@ -68,7 +68,8 @@ private class OptionDeserializer(fullType: JavaType,
if (t == JsonToken.VALUE_NULL) {
getNullValue(ctxt)
} else {
typeDeserializer.deserializeTypedFromAny(jp, ctxt).asInstanceOf[Option[AnyRef]]
val value = valueTypeDeserializer.get.deserializeTypedFromAny(jp, ctxt)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't quite seem right. I believe that this deserializeWithType method is supposed to use the passed in typeDeserializer as an override. I will have to look-through/debug your example/test-case more carefully to see if I can figure out how/why it's passing a deserializer that does not work.

@pjfanning
Copy link
Member

I'm considering merging #537 - basically this PR with merge conflicts fixed

@pjfanning pjfanning closed this Jul 31, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants