Skip to content

Deserializing polymorphic types #1042

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

Closed
dsharp1 opened this issue Dec 10, 2015 · 5 comments
Closed

Deserializing polymorphic types #1042

dsharp1 opened this issue Dec 10, 2015 · 5 comments

Comments

@dsharp1
Copy link

dsharp1 commented Dec 10, 2015

Given a simple polymorphic set of objects, deserialization with jackson 2.6.3 seems to require a custom deserializer in order to correctly serialize the content. It seems like this should be possible to do without using a custom deserializer by using annotations such as what JaxB does with XmlElements. But, I was unable to get it to work in Jackson, and resorted to the custom deserializer. In my custom deserializer, I added a type map by accessing the annotations in order to prevent having to duplicate the entries for the names and type:
Map<String, Class> typeMap = new HashMap<>();
for ( XmlElements elements : MyClass.class.getDeclaredField("myPrivateField").getAnnotationsByType(XmlElements.class) ) {
for ( XmlElement element : elements.value() ) {
typeMap.put( element.name(), element.type() );
}
}

Unfortunately, this tightly couples the field name and the deserializer. Is there a way to do this by accessing the annotations through the context or parser? I could not find a way.

@cowtowncoder
Copy link
Member

Please use mailing list (jackson-users google group) for usage questions.

And yes, Jackson can handle polymorphic deserialization just fine with @JsonTypeInfo, or to some degree with JAXB annotations via JAXB annotations module (although this is not as fully supported).

@dsharp1
Copy link
Author

dsharp1 commented Dec 14, 2015

As demonstrated by two other cases
https://github.com/FasterXML/jackson-databind/issues/1004 and
FasterXML/jackson-module-jaxb-annotations#51,
Jackson definitely does not work with polymorphic types. The reason for
the previous post was to determine if the workaround could be done in a
better way, or if the workaround would help someone find the cause to the
underlying issue in the Jackson code. Within the deserializer override,
there doesn't seem to be an easy way to access the annotations JsonTypeInfo
or XmlElements. For example, if the context had access to the annotations,
the process would be fairly straightforward.

On Thu, Dec 10, 2015 at 6:21 PM, Tatu Saloranta [email protected]
wrote:

Please use mailing list (jackson-users google group) for usage questions.

And yes, Jackson can handle polymorphic deserialization just fine with
@JsonTypeInfo, or to some degree with JAXB annotations via JAXB
annotations module (although this is not as fully supported).


Reply to this email directly or view it on GitHub
#1042 (comment)
.

@cowtowncoder
Copy link
Member

@dsharp1 All that bug says -- and I quote, is: " Jackson interpretation of XMLElements not compatible with JAXB #51 ". Further, that is for XML output which may have (and has...) additional constraints.

You have not provided a reproduction of any failure here, related to core databinding functionality. Or even tried to explain what exactly you think IS THE PROBLEM, but just making an untrue blanket statement. I am busy enough working with actual well-reported problems and do not like guesswork with "hey it doesnt work at all" style reports.

@rpatrick00
Copy link

I think Derek's issue is very much related to JAXB #51, the fact that our customer serializers/deserializers to remove the wrapper elements broke when we moved off of Jackson 2.4.3 to 2.6.3, and the fact that the custom serializer/deserializer interface does not appear to provide any easy way to access the additional type information available from the annotations. We can certainly work this on JAXB #51 instead of creating separate issues if that works better. In fact, we would prefer to not write custom serializers/deserializers at all so if we can eliminate the need to do this for polymorphic types and their collections, then I don;t think we care about accessing the type information from the custom serializers/deserializers.

@cowtowncoder
Copy link
Member

@rpatrick00 Right: declaration information is not available at point of deserializer or deserializeWithType, and that is intentional: it being static information, it is made available during construction. This reduces amount of information passed during critical performance path (deserialization); and also nudges developers to handle it at construction/contextualization.

So: to access annotations, two recommended approaches are:

  1. Implement ContextualDeserializer (and ContextualSerializer for serialization), during which BeanProperty is accessible, allowing inspection of property and enclosing class annotations, as well as other static configuration (MapperConfig), property type.
  2. Register BeanDeserializerModifier, implement modifyDeserializer; much of information is also available here.

Sometimes it may even be necessary to combine these approaches.

Calls to these methods are done when either constructing (de)serializer (with Modifier) for given type; or, when assigning type-based/annotation-specified (de)serializer for given property (contextualization).

I hope this clarifies the intent, and the reason why I specifically am against adding extra information for actual serialization/deserialization calls -- about the only "extra" piece of information that has been added (in 2.6 I think) is the "current value", accessible via JsonGenerator / JsonParser. It gives access to Java object being processed, and can conceivably be used for some level of per-type configuration if necessary.

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

No branches or pull requests

3 participants