question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Deserialization error while using @JsonIdentityReference with resolver

See original GitHub issue

I have a complex entity (ex: ComplexEntity) which has many relations and setters for its properties. Now, to create an instance of this complex entity, I have ComplexEntityController that looks like this:

@RequestMapping("/test")
public void test(ComplexDto dto) {
    complexService.createEntityFromDto(dto);
}

Now assume the following DTO:

public class ComplexDto {
    @JsonIdentityReference(alwaysAsId = true)
    @JsonIdentityInfo(
            generator = ObjectIdGenerators.PropertyGenerator.class,
            property = "id",
            resolver = EntityResolver.class,
            scope = FooEntity.class
    )
    private FooEntity fooEntity;

    public void setFooEntity(FooEntity fooEntity) { this.fooEntity = fooEntity; }
    public FooEntity getFooEntity() { return this.fooEntity; }
}

And the EntityResolver is responsible for loading entities from database.

When I make request to the controller with the following JSON body:

{
    "fooEntity": 3
}

it fails with error: com.fasterxml.jackson.databind.JsonMappingException: Can not find a (Map) Key deserializer for type [simple type, class ir.amir.NiceEntity] since ComplexEntity has a map inside it. This happens, while I just expect jackson to use resolver to load my entity from database and it has nothing to do with the entity since it’s unmeaningful to fill the object while there is a resolver and the passed parameter is just a unique identifier not the whole properties.

Jackson databind version: 2.8.8 with Spring Boot

Thanks

Issue Analytics

  • State:open
  • Created 6 years ago
  • Comments:8 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
cowtowncodercommented, Sep 13, 2017

First of all, thank you for adding the stack trace. It certainly shows that reference chain is quite deep, going through a few POJO types. 😃

I have a feeling that your thinking of how things work is quite different from how Jackson works. Of course it does not deserialize things that are not there. But that is not the point: what it absolute MUST do is traverse type hierarchy to see what handlers are needed. These handlers are looked up once and cached; this makes a big difference in performance over trying to construct deserializers on the fly – you can see the difference by creating new ObjectMapper for each call, and observing 10x - 100x slowdown.

Sometimes it is possible to defer some resolution; other times not. In this case it is not, at least currently.

If there was a simple stand-alone reproduction, I (or someone else with time) could see if it would be possible to improve this particular case, and defer lookup.

As to @JsonIgnoreProperties: that was just a suggestion for working around the need. Alternatively you could register bogus key deserializer for given type; that would work as well. Or, if there are wide varieties of types, register KeyDeserializers via Module to similarly construct not-used placeholders. These are suggestions to let your system work; you are free to use them or not.

0reactions
aronmgvcommented, Jul 20, 2018

@AbiriAmir I am facing exactly the same problem now… did you manage to overcome this problem? It fails for me on null pointer exception since the abstract class has no attributes just children do.

Just simply dont understand why Jackson is not invoking deserializer for that abstract entity…

Read more comments on GitHub >

github_iconTop Results From Across the Web

Jackson jsonidentityinfo deserialization fails - Stack Overflow
The service accepts JSON strings for CRUD commands. I use @JsonIdentityInfo and @JsonIdentityReference in my Server Object, so that the user ...
Read more >
Using @JsonIdentityReference to always serialize a POJO by id
@JsonIdentityInfo allows to serialize a POJO by id but only when it is encountered second time during serialization. @JsonIdentityReference ...
Read more >
Jackson Exceptions - Problems and Solutions - Baeldung
Getting Started with Custom Deserialization in Jackson. Use Jackson to map custom JSON to any java entity graph with full control over the ......
Read more >
Micronaut Serialization
There are no serialization annotations present on this type and an attempt to serialize this type will result in an error. To resolve...
Read more >
Customizing resolving of ObjectIds (from @JsonIdentityInfo ...
As of version 2.4.0 you can use the "resolver" property of the ... property = "id") @JsonIdentityReference(alwaysAsId = true) private List<Article> related;.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found