On Wed, Feb 13, 2019 at 9:10 AM John Passaro <john.a.pass...@gmail.com> wrote:
>
> On Tuesday, February 12, 2019 at 11:43:38 PM UTC-5, John Passaro wrote:
>>
>> On Tue, Feb 12, 2019, 23:02 Tatu Saloranta wrote:
>>>
>>> On Tue, Feb 12, 2019 at 1:18 PM John Passaro wrote:
>>> >
>>> > Hello folks! I am trying to deserialize a yaml file with anchors and 
>>> > references. There are some existing StackOverflow questions along these 
>>> > lines but the answers aren't quite getting me to the finish line.
>>> >
>>> > [...]
>>> >
>>> >
>>> > The idea is that I have lists that may be referenced more than once in 
>>> > the "contents" tree, and I'd like to be able to reference them concisely.
>>> >
>>> > [...]
>>> >
>>> > With Jackson (2.9), I get an error:
>>> >
>>> > Exception in thread "main" 
>>> > com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot 
>>> > deserialize instance of java.util.ArrayList out of VALUE_STRING token
>>> >  at [Source: (File); line: 14, column: 13] (through reference chain: 
>>> > YamlScratch["contents"]->java.util.LinkedHashMap["letters"]->YamlScratch$Config["labels"])
>>> >
>>> > [...]
>>> >
>>> > Is this behavior supported at all? If so, what do I need to do to make it 
>>> > work?
>>> >
>>> > Many thanks in advance for your help. I'd be happy to post the results on 
>>> > the relevant SO threads to make sure this information get shared 
>>> > reasonably widely.
>>>
>>> Ok. I think I can point to the problem itself at least.
>>>
>>> For Jackson to handle anchors and references, property value types (or
>>> property declarations) need `@JsonIdentityInfo`; otherwise Jackson
>>> does not know to look for, or keep track of, anchors (ids for values
>>> to reference) or references.
>>>
>>> But one limitation is that only POJO types support Object Id handling,
>>> and here references would be to Lists of Strings (or maybe Lists of
>>> Lists). In theory it would be possible to handle Object Ids for
>>> Collection, Map and array types, but they are not supported at this
>>> point.
>>>
>>> It might, however, be possible for you to create POJO type that gets
>>> serialized as yaml/json Array, just like List (and deserialized from
>>> as well). This could work by using combination of `@JsonValue` (to get
>>> `List` to serialize) and `@JsonCreator` annotated constructor that
>>> takes actual `List` value you want; or, using Converters. Either way
>>> once you get that working, and type itself annotated with
>>> `@JsonIdentityInfo` it should work.
>>>
>>> I know this is sub-optimal and leaves out some valid YAML cases. But
>>> it just might work for your usage.
>>>
>>> I hope this helps,
>>>
>>> -+ Tatu +-
>>
>>
>> I will certainly try this out, it does seem like it would address my need. 
>> Thank you for the close attention to the example and for your suggestion. If 
>> it works I'll post my findings (i.e. working example) here and maybe add to 
>> those SO questions.
>>
>> It seems to me there might be a friendlier experience if there was a 
>> YamlParser.Feature to treat the entire document as having the 
>> JsonIdentityInfo annotation, including Lists and Maps and their contents - 
>> that is, resolving anchor references everywhere without the need for 
>> indicating where the user expects them to be. I don't know enough to assert 
>> that this is closer to the intention of the anchor/reference feature or of 
>> an average document that uses it, but it is closer to how PyYAML treats 
>> them, which I've found very useful. I hope you'll consider supporting such 
>> usage.
>>
>> Regardless, thank you for your help and for your work on this powerful 
>> library.
>>
> Sadly this did not work. Here is my best shot based on how I understood the 
> suggestion:
>
> @JsonIdentityInfo(generator = ObjectIdGenerators.None.class)
> class ScratchModel {
>     @JsonProperty("contents")
>     @JsonIdentityInfo(generator = ObjectIdGenerators.None.class)
>     Map<String, Config> contents;
>
>     @JsonProperty("misc")
>     @JsonIdentityInfo(generator = ObjectIdGenerators.None.class)
>     Misc misc;
>
>     @JsonIdentityInfo(generator = ObjectIdGenerators.None.class)
>     static class Config {
>         @JsonProperty("header")
>         String header;
>
>         @JsonProperty("labels")
>         @JsonIdentityInfo(generator = ObjectIdGenerators.None.class)
>         List<String> labels;
>
>     }
>
>     @JsonIdentityInfo(generator = ObjectIdGenerators.None.class)
>     private static class Misc {
>         @JsonCreator
>         Misc(List<MiscInner> inners) { }
>     }
>
>
>     @JsonIdentityInfo(generator = ObjectIdGenerators.None.class)
>     private static class MiscInner {
>         @JsonCreator
>         MiscInner(List<String> strings) { }
>     }
> }
>
> So I broke down the "misc" field, previously List<List<String>>, into a type 
> Misc that creates itself from List<MiscInner>, and MiscInner which creates 
> itself from List<String>. I added the @JsonIdentityInfo annotation to every 
> class and property that could plausibly need it.

So, looks legit; you should not need `@JsonIdentityInfo` on properties
with value types that already have them.

As to the problem, I think what would help is if this could be
distilled into minimal reproduction, to maybe see what is triggering
the failure.

-+ Tatu +-

>
> Still getting the same error!
>
> Here is the failing YAML again, for reference:
>
> misc:
>   - &letters
>     - Aie
>     - Bee
>     - See
>   - &numbers
>     - One
>     - Two
>     - Three
>
> contents:
>   letters:
>     header: "This is a list of phonetic letters"
>     labels: *letters
>   numbers:
>     header: "This is a list of number spellings"
>     labels: *numbers
>   moreletters:
>     header: "this is another copy of the letters"
>     labels: *letters
>
> --
> You received this message because you are subscribed to the Google Groups 
> "jackson-user" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to jackson-user+unsubscr...@googlegroups.com.
> To post to this group, send email to jackson-user@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google Groups 
"jackson-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to jackson-user+unsubscr...@googlegroups.com.
To post to this group, send email to jackson-user@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to