Skip to content

No way to combine @JsonTypeInfo(include = As.PROPERTY) and @JsonIdentityInfo(generator = PropertyGenerator.class) #4014

@knutwannheden

Description

@knutwannheden

Describe the bug
I have tried many different ways to combine @JsonTypeInfo(include = As.PROPERTY) and @JsonIdentityInfo(generator = PropertyGenerator.class), but it always ends up throwing an exception at me like this one:

com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Invalid Object Id definition for `foo.JacksonDeserializationTest$BaseEntity`: cannot find property with name '@id'
 at [Source: (String)"{"@c":"foo.JacksonDeserializationTest$Bar","@id":1,"foo":{"@c":"foo.JacksonDeserializationTest$Foo","@id":0,"other":1}}"; line: 1, column: 1]

	at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:67)
	at com.fasterxml.jackson.databind.DeserializationContext.reportBadDefinition(DeserializationContext.java:1915)
	at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:268)
	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.findNonContextualValueDeserializer(DeserializationContext.java:644)
	at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.resolve(BeanDeserializerBase.java:539)
	at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:294)
	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:654)
	at com.fasterxml.jackson.databind.ObjectMapper._findRootDeserializer(ObjectMapper.java:4956)
	at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4826)
	at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3772)
	at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3740)

Version information
2.15.2

To Reproduce

class JacksonDeserializationTest {

    @Test
    void test() throws Exception {
        Foo foo = new Foo();
        Bar bar = new Bar();
        foo.setOther(bar);
        bar.setFoo(foo);

        ObjectMapper mapper = new ObjectMapper();
        System.out.println(mapper.writeValueAsString(bar));
        Bar deserialized = mapper.readValue(mapper.writeValueAsString(bar), Bar.class);
    }

    @JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "@c")
    @JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "@id")
    public interface BaseEntity {
        class Id {
            static int next = 0;
        }
        @JsonProperty("@id")
        Integer getId();
    }

    public static class Foo implements BaseEntity {
        private BaseEntity other;
        private Integer id = Id.next++;

        @Override
        public Integer getId() {
            return id;
        }

        public BaseEntity getOther() {
            return other;
        }

        public void setOther(BaseEntity other) {
            this.other = other;
        }
    }

    public static class Bar implements BaseEntity {
        private BaseEntity foo;

        private Integer id = Id.next++;

        @Override
        public Integer getId() {
            return id;
        }

        public BaseEntity getFoo() {
            return foo;
        }

        public void setFoo(BaseEntity foo) {
            this.foo = foo;
        }
    }
}

Expected behavior
It seems like it should be possible to combine these two features somehow. I have tried all combinations I can think of, but couldn't get it to work, so I assume there must be some bug here.

Additional context
I have a set of Java objects I want to serialize, where the references in the object graph form many cycles, so I need to use @JsonIdentityInfo for this. Also, I have an inheritance hierarchy, so I need to use @JsonTypeInfo to cover this.

Metadata

Metadata

Assignees

No one assigned

    Labels

    3.2has-failing-testIndicates that there exists a test case (under `failing/`) to reproduce the issue

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions