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

JsonTypeInfo.As.EXTERNAL_PROPERTY does not work with a Delegate #1003

Closed
alexwen opened this issue Nov 12, 2015 · 6 comments
Closed

JsonTypeInfo.As.EXTERNAL_PROPERTY does not work with a Delegate #1003

alexwen opened this issue Nov 12, 2015 · 6 comments
Milestone

Comments

@alexwen
Copy link

alexwen commented Nov 12, 2015

I am using a library which generates the Jackson deserialization code as a delegate. I have created a class here which simulates this format:

public class HeroBattle {

    private final Hero hero;

    private HeroBattle(Hero hero) {
        this.hero = requireNonNull(hero);
    }

    @JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.EXTERNAL_PROPERTY, property = "heroType")
    public Hero getHero() {
        return hero;
    }

    @JsonCreator
    static HeroBattle fromJson(Delegate json) {
        return new HeroBattle(json.hero);
    }

    public class Delegate {
        @JsonProperty
        @JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.EXTERNAL_PROPERTY, property = "heroType")
        Hero hero;
    }

    public static void main(String[] args) throws IOException {
        ObjectMapper mapper = new ObjectMapper();

        final String json = mapper.writeValueAsString(new HeroBattle(new Superman()));
        final HeroBattle battle = mapper.readValue(json, HeroBattle.class);

        assert battle.getHero() instanceof Superman;
    }

    public interface Hero {
    }

    public static class Superman implements Hero {
        public String getName() {
            return "superman";
        }
    }
}

This results in the following exception:

Exception in thread "main" java.lang.IllegalStateException: No default constructor for [simple type, class HeroBattle]
    at com.fasterxml.jackson.databind.deser.std.StdValueInstantiator.createUsingDefault(StdValueInstantiator.java:211)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeWithExternalTypeId(BeanDeserializer.java:652)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:262)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:124)
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3066)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2161)
    at HeroBattle.main(HeroBattle.java:43)
@cowtowncoder
Copy link
Member

Ok that may be a bug. One thing you may want to try is to add mode property for @JsonCreator, with value Mode.DELEGATING. It should not be necessary, but with possibility of confusion between single-property creator and delegating one that could be one reason for failure.

I assume this is (or can be reproduced) with Jackson 2.6.3?

@alexwen
Copy link
Author

alexwen commented Nov 12, 2015

Yes, sorry should have said the version. I originally found the issue in 2.4.6 but verified it in 2.6.3 as well.

Specifying Mode.Delegating does not change the exception that is thrown.

cowtowncoder added a commit that referenced this issue Nov 25, 2015
@cowtowncoder
Copy link
Member

I can reproduce the issue locally; added a failing unit test. No idea yet as to what causes this.

@cowtowncoder
Copy link
Member

Actually looks like this specific combination of "exotic" features is just not yet supported, unlike, say, property-based creator and external type id. Will try to see if it'd be easy enough to add support.

cowtowncoder added a commit that referenced this issue Nov 25, 2015
@cowtowncoder cowtowncoder modified the milestones: 1.9.13, 2.6.4 Nov 25, 2015
@cowtowncoder
Copy link
Member

Took a while to figure this out, but I think I solved it the way it should be solved; test had one minor flaw (no setter for Superman), but after fixing that also test passes.

@alexwen
Copy link
Author

alexwen commented Nov 25, 2015

Awesome! Thanks for the fix!

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

2 participants