/JsonIdentityInfoAlwaysAsObjectSerializationJackson

Jackson @JsonIdentityInfo Always As Object Serialization Demo

Primary LanguageJava

This is demo project for different serialization approaches when @JsonIdentityInfo is used

It is more like a hack, but worked for me just fine, because i wasn't using id fields generated by @JsonIdentityInfo and was fine with disabling @JsonIdentityInfo annotation introspection during serialization. And this approach will remove @id field if it is only generated by @JsonIdentityInfo(property="@id") annotation and has no real field.

JsonIdentityInfoAlwaysAsObjectSerializationJackson$
ObjectMapper mapper = new ObjectMapper();
SerializationConfig config = mapper.getSerializationConfig()
        .with(new JacksonAnnotationIntrospector() {
            @Override
            public ObjectIdInfo findObjectIdInfo(final Annotated ann) {
                // can perform class check if you need it
                return null;
            }
        });

mapper.setConfig(config);
  1. @JsonIdentityInfo - Always Serialize IDs as Fields Issues #372
  2. More info: https://stackoverflow.com/a/46610026/1032167
  3. My example gist demo

This demo project can deserialize every version of:

{ "phones":[1,2,1] }
{ "phones":[{ "id":1 }, { "id":2 }, { "id":1 }]}
{ "phones":[{ "id":1 }, { "id":2 }, 1]}

Achieved with custom ObjectIdResolver


And serialise it to one of the same outputs.

  1. Always as reference by default:

    { "phones":[1,2,1] }
    
  2. Object first appearance and reference after

    This is jackson default ID/reference mechanism without @JsonIdentityReference so you can just remove @JsonIdentityReference(alwaysAsId = true) annotations

    Or if you cant remove annotations for some reason, can try custom ObjectMapper

    { "phones":[{ "id":1 }, { "id":2 }, 1]}
    
  3. Always as object With another custom ObjectMapper

    { "phones":[{ "id":1 }, { "id":2 }, { "id":1 }]}   
    

Output of this demo project is

ObjectMapper1 without customisations
Serialization tests:
Contact      : {"id":1,"phones":[3,2,3]}
List<Contact>: [{"id":1,"phones":[3,2,3]},{"id":1,"phones":[3,2,3]}]
Deserialization tests:
From: {"id":1,"phones":[{"id":3,"n":"a"},{"id":2,"n":null},3]}
To  : {"id":1,"phones":[3,2,3]}
From: {"id":1,"phones":[{"id":3,"n":"b"},{"id":2,"n":null},{"id":3,"n":"b"}]}
To  : {"id":1,"phones":[3,2,3]}
From: {"id":1,"phones":[1,2,1]}
To  : {"id":1,"phones":[1,2,1]}

ObjectMapper2 with ignoreJsonIdentityInfoMapper
Serialization tests:
Contact      : {"id":1,"phones":[{"id":3,"n":"b"},{"id":2,"n":"a"},{"id":3,"n":"b"}]}
List<Contact>: [{"id":1,"phones":[{"id":3,"n":"b"},{"id":2,"n":"a"},{"id":3,"n":"b"}]},{"id":1,"phones":[{"id":3,"n":"b"},{"id":2,"n":"a"},{"id":3,"n":"b"}]}]
Deserialization tests:
From: {"id":1,"phones":[{"id":3,"n":"a"},{"id":2,"n":null},3]}
To  : {"id":1,"phones":[{"id":3,"n":"a"},{"id":2,"n":null},{"id":3,"n":"a"}]}
From: {"id":1,"phones":[{"id":3,"n":"b"},{"id":2,"n":null},{"id":3,"n":"b"}]}
To  : {"id":1,"phones":[{"id":3,"n":"b"},{"id":2,"n":null},{"id":3,"n":"b"}]}
From: {"id":1,"phones":[1,2,1]}
To  : {"id":1,"phones":[{"id":1,"n":null},{"id":2,"n":null},{"id":1,"n":null}]}

ObjectMapper3 with ignoreJsonIdentityReferenceMapper
Serialization tests:
Contact      : {"id":1,"phones":[{"id":3,"n":"b"},{"id":2,"n":"a"},{"id":3,"n":"b"}]}
List<Contact>: [{"id":1,"phones":[{"id":3,"n":"b"},{"id":2,"n":"a"},{"id":3,"n":"b"}]},{"id":1,"phones":[{"id":3,"n":"b"},{"id":2,"n":"a"},{"id":3,"n":"b"}]}]
Deserialization tests:
From: {"id":1,"phones":[{"id":3,"n":"a"},{"id":2,"n":null},3]}
To  : {"id":1,"phones":[{"id":3,"n":"a"},{"id":2,"n":null},{"id":3,"n":"a"}]}
From: {"id":1,"phones":[{"id":3,"n":"b"},{"id":2,"n":null},{"id":3,"n":"b"}]}
To  : {"id":1,"phones":[{"id":3,"n":"b"},{"id":2,"n":null},{"id":3,"n":"b"}]}
From: {"id":1,"phones":[1,2,1]}
To  : {"id":1,"phones":[{"id":1,"n":null},{"id":2,"n":null},{"id":1,"n":null}]}