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

Typed object throws "Missing type id" when annotated with @JsonIdentityInfo #232

Closed
almson opened this issue Nov 14, 2020 · 13 comments
Closed
Labels
has-failing-test Indicates that there exists a test case (under `failing/`) to reproduce the issue yaml Issue related to YAML format backend
Milestone

Comments

@almson
Copy link

almson commented Nov 14, 2020

Tested with Jackson 2.12.0-rc2-SNAPSHOT

import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonSubTypes.Type;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.JsonTypeInfo.Id;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import java.util.List;
import org.junit.Test;

public class JacksonYamlTest {
    
    static class Container {
        @JsonProperty
        List<Base> list;
    }
    
    @JsonTypeInfo(use = Id.NAME)
    @JsonSubTypes({@Type(name="Derived", value=Derived.class)})
    @JsonIdentityInfo(generator = ObjectIdGenerators.StringIdGenerator.class)
    static class Base {
        
    }
    
    static class Derived extends Base {
        @JsonProperty
        String a;
    }
    
    @Test
    public void typedTestYaml() throws Exception {
        
        String yaml = "list:\n" +
                      "    - !Derived\n" +
                      "        a: foo";
        
        ObjectMapper mapper = new ObjectMapper (new YAMLFactory());
        Container container = mapper.readValue (yaml, Container.class);
        
        System.out.println (((Derived)container.list.get(0)).a);
    }
    
    @Test
    public void typedTestJson() throws Exception {
        
        String json = "{\"list\":[{\"@type\":\"Derived\",\"a\":\"foo\"}]}";
        
        ObjectMapper mapper = new ObjectMapper();
        Container container = mapper.readValue (json, Container.class);
        
        System.out.println (((Derived)container.list.get(0)).a);
    }
}

typedTestYaml throws:

com.fasterxml.jackson.databind.exc.InvalidTypeIdException: 
Missing type id when trying to resolve subtype of [simple type, class JacksonYamlTest$Base]: missing type id property '@type' (for POJO property 'list')
 at [Source: (StringReader); line: 3, column: 15] (through reference chain: JacksonYamlTest$Container["list"]->java.util.ArrayList[0])
	at com.fasterxml.jackson.databind.exc.InvalidTypeIdException.from(InvalidTypeIdException.java:43)
	at com.fasterxml.jackson.databind.DeserializationContext.missingTypeIdException(DeserializationContext.java:1945)
	at com.fasterxml.jackson.databind.DeserializationContext.handleMissingTypeId(DeserializationContext.java:1458)
	at com.fasterxml.jackson.databind.jsontype.impl.TypeDeserializerBase._handleMissingTypeId(TypeDeserializerBase.java:307)
	at com.fasterxml.jackson.databind.jsontype.impl.AsPropertyTypeDeserializer._deserializeTypedUsingDefaultImpl(AsPropertyTypeDeserializer.java:174)
	at com.fasterxml.jackson.databind.jsontype.impl.AsPropertyTypeDeserializer.deserializeTypedFromObject(AsPropertyTypeDeserializer.java:113)
	at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeWithType(BeanDeserializerBase.java:1277)
	at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer._deserializeWithObjectId(CollectionDeserializer.java:443)
	at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer._deserializeFromArray(CollectionDeserializer.java:334)
	at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:244)
	at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:28)
	at com.fasterxml.jackson.databind.deser.impl.FieldProperty.deserializeAndSet(FieldProperty.java:138)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:324)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:187)
	at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:322)
	at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4591)
	at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3546)
	at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3514)
	at JacksonYamlTest.typedTestYaml(JacksonYamlTest.java:54)com.fasterxml.jackson.databind.exc.InvalidTypeIdException: 
Missing type id when trying to resolve subtype of [simple type, class JacksonYamlTest$Base]: missing type id property '@type' (for POJO property 'list')
 at [Source: (StringReader); line: 3, column: 15] (through reference chain: JacksonYamlTest$Container["list"]->java.util.ArrayList[0])
	at com.fasterxml.jackson.databind.exc.InvalidTypeIdException.from(InvalidTypeIdException.java:43)
	at com.fasterxml.jackson.databind.DeserializationContext.missingTypeIdException(DeserializationContext.java:1945)
	at com.fasterxml.jackson.databind.DeserializationContext.handleMissingTypeId(DeserializationContext.java:1458)
	at com.fasterxml.jackson.databind.jsontype.impl.TypeDeserializerBase._handleMissingTypeId(TypeDeserializerBase.java:307)
	at com.fasterxml.jackson.databind.jsontype.impl.AsPropertyTypeDeserializer._deserializeTypedUsingDefaultImpl(AsPropertyTypeDeserializer.java:174)
	at com.fasterxml.jackson.databind.jsontype.impl.AsPropertyTypeDeserializer.deserializeTypedFromObject(AsPropertyTypeDeserializer.java:113)
	at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeWithType(BeanDeserializerBase.java:1277)
	at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer._deserializeWithObjectId(CollectionDeserializer.java:443)
	at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer._deserializeFromArray(CollectionDeserializer.java:334)
	at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:244)
	at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:28)
	at com.fasterxml.jackson.databind.deser.impl.FieldProperty.deserializeAndSet(FieldProperty.java:138)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:324)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:187)
	at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:322)
	at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4591)
	at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3546)
	at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3514)
	at JacksonYamlTest.typedTestYaml(JacksonYamlTest.java:54)
@cowtowncoder cowtowncoder added the yaml Issue related to YAML format backend label Nov 22, 2020
@cowtowncoder cowtowncoder changed the title YAML: Typed object throws "Missing type id" when annotated with @JsonIdentityInfo Typed object throws "Missing type id" when annotated with @JsonIdentityInfo Nov 22, 2020
@cowtowncoder
Copy link
Member

cowtowncoder commented Nov 22, 2020

Note: possibl related to #25.

cowtowncoder added a commit that referenced this issue Nov 22, 2020
@cowtowncoder cowtowncoder added the has-failing-test Indicates that there exists a test case (under `failing/`) to reproduce the issue label Nov 22, 2020
@cowtowncoder
Copy link
Member

Added failing test based on example.

@cowtowncoder
Copy link
Member

Not sure what to do but noting that this is probably related to buffering of Type and/or Object Ids: TokenBuffer does hold on to them, but looks like type id is associated with MappingStart event, not name part that follows. I suspect this is similar to how Object Id handling is delayed, and should be handled same way... but not sure how to, yet.

@cowtowncoder
Copy link
Member

On further inspection, no buffering involved in this particular case. But type-id is off between cases: without @JsonIdentityInfo, type id asked at START_OBJECT and is found; with it asked on following FIELD_NAME and no longer available.

@cowtowncoder cowtowncoder added this to the 2.12.0 milestone Nov 24, 2020
@benjaminwiegand
Copy link

benjaminwiegand commented Jun 28, 2022

What was the solution to this?
@cowtowncoder
I tried to add @JsonIdentiyInfo with ids but I got the same error message.

@yawkat
Copy link
Member

yawkat commented Jun 28, 2022

@benjaminwiegand it was fixed in this commit: 2a07652

Do you still have the error in the latest jackson version?

@benjaminwiegand
Copy link

benjaminwiegand commented Jun 28, 2022

Yes I do (jackson 2.12.1). See below for code. What am I missing? @yawkat @cowtowncoder

@benjaminwiegand
Copy link

benjaminwiegand commented Jun 28, 2022

I have a classes:

public class TownHouse(){
   ArrayList<Garage> garages;
  ... other stuff here ...
} 
public Class Garage() {
 @JsonProperty
 ArrayList<Bike> bikes;
 @JsonProperty
 String location;
}

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.AsPROPERTY, property = "type")
@JsonSubTypes({@JsonSubTypes.Type(value = TrickBike.class, name ="TrickBike),
                            @JsonSubTypes.Type(value = JumpBike.class, name ="JumpBike),
                            @JsonSubTypes.Type(value = MountainBike.class, name ="MountainBike),
                            @JsonSubTypes.Type(value = Bike.class, name ="Bike),
})
@JsonTypeName("Bike")
public class Bike{
    int numWheels;
}
@JsonTypeName("TrickBike")
public class TrickBike extends Bike{
     ... other stuff here...
}
@JsonTypeName("JumpBike")
public class JumpBike extends Bike{
         ... other stuff here...

}
@JsonTypeName("MountainBike")
public class MountainBike extends Bike{
     ... other stuff here...

}

And I'm getting, InvalidTypeException: Missing type id when trying to resolve subtype of [simple type, class Bike]: missing type id property 'type' for pojo property bikes when I:

Townhouse th = ....
<add some garages> 
<add some bikes> 
ObjectMapper mapper = new ObjectMapper();
mapper.writeValueAsString(th);


I tried adding @JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class, property = "@id") but that didn't do anything.

I believe I'm missing some annotation somewhere but not sure where.

@benjaminwiegand
Copy link

I fixed it.

@yawkat
Copy link
Member

yawkat commented Jun 29, 2022

your code does not use yaml though? this was specifically a yaml issue

@githubshivi
Copy link

@benjaminwiegand how did you fixed that issue i'm also facing the same issue

@Hassaballah101
Copy link

@benjaminwiegand useless comment when u don't say the solution :)

@cowtowncoder
Copy link
Member

cowtowncoder commented May 10, 2024

Original issue was fixed so things should work: perhaps it was a matter of upgrading Jackson YAML module version used.

If you still have problems, please file new issue -- we usually do not re-open old issues since that complicates release note handling (and often follow-up issues are different from original anyway).

You may refer to this issue as background info but the new issue should have reproduction and not assume it is the same root problem; even if the failure message looks the same does not necessarily mean identical issue.
Possibly related (hence ref to this issue can be useful).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
has-failing-test Indicates that there exists a test case (under `failing/`) to reproduce the issue yaml Issue related to YAML format backend
Projects
None yet
Development

No branches or pull requests

6 participants