jsr367-experts@jsonb-spec.java.net

[jsr367-experts] Re: [jsonb-spec users] Re: Re: Polymorphic deserializer

From: Roman Grigoriadi <roman.grigoriadi_at_oracle.com>
Date: Tue, 10 May 2016 16:47:13 +0200

But what if root is a part of deserialized subpart of the tree?

class Part {
...
List<Subpart>
}

class Subpart {
...
Part child;
}

now in PartDeserializer you call ctx.deserialize( new
TokenImpl<List<Subpart>>() {}.getRuntimeType()) ?

On 05/10/2016 04:29 PM, Romain Manni-Bucau wrote:
> case I had in mind was when you only deserialize a subpart of the tree
> and not the root directly. At each level you can prevent to re-enter
> in the same deserializer but you can need it later in the tree.
>
>
> Romain Manni-Bucau
> @rmannibucau
> http://www.tomitribe.com
> http://rmannibucau.wordpress.com
> https://github.com/rmannibucau
>
> 2016-05-10 16:02 GMT+02:00 Roman Grigoriadi
> <roman.grigoriadi_at_oracle.com <mailto:roman.grigoriadi_at_oracle.com>>:
>
> Is there a usecase where you actually may need reentrant
> deserialize() calls, with recursive models?
>
> When you call context.deserialize() inside deserializer, even for
> other type than deserializer return type, you may still encounter
> deserialization into return type of deserializer inside.
>
> Roman
>
>
> On 05/10/2016 03:49 PM, Romain Manni-Bucau wrote:
>> Hi Roman,
>>
>> We encountered it in johnzon when Mark implemented it. We chose
>> to just prevent these loops since they can easily be detected at
>> framework level but not expose it to the end user.
>>
>> typically in your code it would be:
>>
>> ctx.deserialize(clazz, parser) { // pseudo code
>> return this.deserialize(clazz, parser, <ignorePolymorphicDeserializer for root level *only*>);
>> }
>> Note: in this snippet it would be great to not require the hasNext to be called (ie if called ok but if not then deserialize can do it).
>>
>>
>>
>> Romain Manni-Bucau
>> @rmannibucau
>> http://www.tomitribe.com
>> http://rmannibucau.wordpress.com
>> https://github.com/rmannibucau
>>
>> 2016-05-10 15:42 GMT+02:00 Roman Grigoriadi
>> <roman.grigoriadi_at_oracle.com <mailto:roman.grigoriadi_at_oracle.com>>:
>>
>> According to polymorphic deserialization, which was one of
>> the usecases for deserializers, I encountered the fact, that
>> if context.deserialize() is called inside the deserializer
>> for the type that is the return type for that deserializer,
>> jsonb runtime will try to use such deserializer again inside.
>> Example:
>>
>> public class PolymorphicDeserializerimplements JsonbDeserializer<Animal> {
>> @Override public Animal deserialize(JsonParser parser, DeserializationContext ctx, Type rtType) {
>> Class<?extends Animal> clazz =null;
>>
>> while (parser.hasNext()) {
>> //some code to get class, which will result to subclass of an
>> Animal
>> //...
>> //following will cause adding PolymorphicDeserializer
>> instance to call stack again, calling deserialize on it
>> return ctx.deserialize(clazz, parser);//--- REENTRANT CALL---
>> }
>> throw new IllegalStateException("animal not found!");
>> }
>> }
>>
>> Looks like this is correct behaviour, JSONB runtime has
>> deserializer registered for it. Without some kind of
>> parameter flag it has no clue not to use it. How about adding
>> default to true method "boolean isReentrant()" to
>> JsonbDeserializer interface?
>>
>> Thanks,
>> Roman
>>
>>
>
>