Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JsonUnwrapped not working properly with ConstructorProperties #1274

Closed
lukaszrek opened this issue Jun 22, 2016 · 7 comments
Closed

JsonUnwrapped not working properly with ConstructorProperties #1274

lukaszrek opened this issue Jun 22, 2016 · 7 comments

Comments

@lukaszrek
Copy link

After migrating to Jackson 2.7.5 from Jackson 2.6 I found weird interaction between JsonUnwrapped and ConstructorProperties. See following test.

public class JacksonTest {

    @Test
    public void shouldDeserializeValueObjectWithUnwrappedProperty() throws Exception {
        ObjectMapper mapper = new ObjectMapper();
        Outer outer = mapper.readValue("{ \"value\" : 1, \"nested1\" : 2, \"nested2\" : 3 }", Outer.class);

        assertThat(outer.value, is(1));
        assertThat(outer.nested.nested1, is(2));
        assertThat(outer.nested.nested2, is(3));
    }

    @RequiredArgsConstructor
    private static class Outer {
        private final int value;

        @JsonUnwrapped
        private final Nested nested;
    }

    @RequiredArgsConstructor
    private static class Nested {
        private final int nested1;
        private final int nested2;
    }
}

Just for clarity, after delomboking, value objects have following definitions:

    private static class Outer {
        private final int value;

        @JsonUnwrapped
        private final Nested nested;

        @java.beans.ConstructorProperties({"value", "nested"})
        public Outer(int value, Nested nested) {
            this.value = value;
            this.nested = nested;
        }
    }

    private static class Nested {
        private final int nested1;
        private final int nested2;

        @java.beans.ConstructorProperties({"nested1", "nested2"})
        public Nested(int nested1, int nested2) {
            this.nested1 = nested1;
            this.nested2 = nested2;
        }
    }

Running test gives stack trace:

com.fasterxml.jackson.databind.JsonMappingException: Could not find creator property with name 'nested' (in class com.egnyte.delphi.cloudapp.common.jackson.ObjectMapperProviderUnitTest$Outer)
 at [Source: { "value" : 1, "nested1" : 2, "nested2" : 3 }; line: 1, column: 1]

    at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:261)
    at com.fasterxml.jackson.databind.DeserializationContext.reportMappingException(DeserializationContext.java:1233)
    at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.addBeanProps(BeanDeserializerFactory.java:553)
    at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.buildBeanDeserializer(BeanDeserializerFactory.java:227)
    at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.createBeanDeserializer(BeanDeserializerFactory.java:142)
    at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer2(DeserializerCache.java:406)
    at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer(DeserializerCache.java:352)
    at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:264)
    at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCacheValueDeserializer(DeserializerCache.java:244)
    at com.fasterxml.jackson.databind.deser.DeserializerCache.findValueDeserializer(DeserializerCache.java:142)
    at com.fasterxml.jackson.databind.DeserializationContext.findRootValueDeserializer(DeserializationContext.java:475)
    at com.fasterxml.jackson.databind.ObjectMapper._findRootDeserializer(ObjectMapper.java:3890)
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3785)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2833)

I found workaround for this problem. I need to add @JsonProperty annotation to field annotated with @JsonUnwrapped :

    @RequiredArgsConstructor
    private static class Outer {
        private final int value;

        @JsonProperty("nested")
        @JsonUnwrapped
        private final Nested nested;
    }

With this addition test passes. However it would be nice if @JsonPropery is not needed here.

@cowtowncoder
Copy link
Member

Hmmh. That is odd. Basically name of unwrapped property should be mostly ignored (it's a placeholder really). Well, sort of; I guess in this case it is unfortunately needed to link the logical property, passed via constructor. So I guess this is a problem. There are some observed issues with linking creator properties to non-creator properties, related to resolution of creator properties, and the whole system needs to be rewritten. But due to complexity that will be done at earliest for 2.9. So your work-around is good to have for now.,

@wayerr
Copy link

wayerr commented Jan 16, 2017

I found same issue, debugging show that, creatorProps array (in com.fasterxml.jackson.databind.deser.BeanDeserializerFactory#addBeanProps) contains, very strange property:
[creator property, name '@JsonUnwrapped'; inject id 'null'] but code try to find [Property 'nested'; ctors: [parameter #0, .... So adding @JsonProperty("nested") force right creator property name and therefore fix issue.

@wayerr
Copy link

wayerr commented Jan 16, 2017

But i see that usage of @JsonUnwrapped in ctor marked as bug and will raise error in future version at 2e7f74f

right?

@cowtowncoder
Copy link
Member

@wayerr Most likely yes. Ideally it should be supported, eventually, but probably not before 3.x. The current implementation of unwrapped properties can not be made to support this reliably.

@cowtowncoder
Copy link
Member

I think there is another issue noting problems between @JsonUnwrapped and @JsonCreator, so closing this issue as duplicate (or now).

@jakub-bochenski
Copy link

I think there is another issue noting problems between @JsonUnwrapped and @JsonCreator, so closing this issue as duplicate (or now).

@cowtowncoder Can you link to that other issue?

@cowtowncoder
Copy link
Member

So: #1467 is the remaining "main" issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants