jackson-databind icon indicating copy to clipboard operation
jackson-databind copied to clipboard

Deserialization with Default Typing (PTH) and `@JsonIdentityInfo` in untyped collections

Open alex-t0 opened this issue 4 years ago • 5 comments

I need to serialize/deserialize untyped collections, and I get issue when deserialing. I push failing unit test in my repository: https://github.com/alex-t0/deserialization-fail-example/blob/master/src/test/java/deserialization/fail/example/DeserializationFromUntypedCollectionsTest.java.

In this test I have simple User class and dummy UserContainer class, that has one User property. Next, I create an array of 2 elements: user and userContainer with reference to same user.

When first element of array is user, and second is container - deserialization works fine. I get this serialized string:

[
    "java.util.ArrayList",
    [
        [
            "deserialization.fail.example.User",
            {
                "id": 42,
                "login": "cool_man"
            }
        ],
        [
            "deserialization.fail.example.UserContainer",
            {
                "user": 42
            }
        ]
    ]
]

Because jackson knows what is 42 here.

But if I put userContainer at first place in my array, and user at second place, serialized data would be

[
    "java.util.ArrayList",
    [
        [
            "deserialization.fail.example.UserContainer",
            {
                "user": [
                    "deserialization.fail.example.User",
                    {
                        "id": 42,
                        "login": "cool_man"
                    }
                ]
            }
        ],
        42
    ]
]

So, user serialized as id, but no type information saved about user. And when I deserialize this I get an array with Integer 42 at second place, not user.

I think that when serializing untyped collection jackson must "start from scratch" for every element, and "forget" previously found object id's. Size of json will increase, but will work.

Maу be somebody offer better solution.

Thanks!

alex-t0 avatar Jul 02 '20 06:07 alex-t0

Or, I think may be more appropriated approach, wrap object Id into type information. For me all approaches are fine, if only deserialization works fine :)

alex-t0 avatar Jul 02 '20 07:07 alex-t0

Some additional notes: this uses Hibernate module, and I suspect this may be what causes issues, possibly due to proxy classes (since those could break identity handling), or possibly since module itself has not been maintained well (it has no owner and is unlikely to be included with Jackson 3.x unless an owner/maintainer found)

If possible, it'd be good to try out alternate test without this module.

Another thing to try out is to leave DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES enabled -- disabling it can hide legit errors, so during testing it is usually good to enable.

cowtowncoder avatar Jul 02 '20 17:07 cowtowncoder

Hi @cowtowncoder!

I just created no-hibernate branch, and enable DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES option.

And I got same exception.

Please see https://github.com/alex-t0/deserialization-fail-example/commit/5c38fd45b4588ad345528f90947620a16be859f8

alex-t0 avatar Jul 02 '20 19:07 alex-t0

Ok thanks. I hope to have to look into this in near future: removal of hibernate from test should help pinpoint issue itself.

cowtowncoder avatar Jul 02 '20 20:07 cowtowncoder

@cowtowncoder, may be you remove hibernate label from this issue? And thank you for help!

alex-t0 avatar Jul 02 '20 21:07 alex-t0