Skip to content

Bug in polymorphic deserialization with @JsonCreator, @JsonAnySetter, JsonTypeInfo.As.EXTERNAL_PROPERTY #3045

@martineaus83

Description

@martineaus83

I'm using Jackson for a while in simply way. I've just tried some more difficult tricks and I found a strange behaviour.

When I've combined JsonCreator annotation with a JsonTypeInfo.As.EXTERNAL_PROPERTY resolver, then the result is not the same than if I had not put the @JsonCreator.

My example is simple : I want to deserialize this String :

{ "time":345,
  "type":"track",
  "data":{"data-internal":"toto"}
}

My classes are


	public static class MyData {
		@JsonAnySetter
		public HashMap data = new HashMap();
		@Override
		public String toString() {
			StringBuilder buf = new StringBuilder();
			buf.append("[");
			Set<Entry> entrySet = data.entrySet();
			for (Entry e : entrySet) {
				buf.append("[").append(e.getKey()).append("=").append(e.getValue()).append("]");
			}
			buf.append("]");
			return buf.toString();
		}
	}

	public static class MyJson {
		private long time;
		private String type;
		private Object data;

		public MyJson() {
		}
		public long getTime() {
			return time;
		}
		public void setTime(long time) {
			this.time = time;
		}
		public String getType() {
			return type;
		}
		public void setType(String type) {
			this.type = type;
		}
		public Object getData() {
			return data;
		}
		@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.EXTERNAL_PROPERTY, property = "type")
		@JsonTypeIdResolver(ChildBaseByParentTypeResolver.class)
		public void setData(Object data) {
			this.data = data;
		}
	}

	public static class MyJson2 {
		private final long time;
		private String type;
		private Object data;

		@JsonCreator
		public MyJson2(@JsonProperty("time") long t) {
			System.out.println("MyJson2<init>");
			time = t;
		}
		public long getTime() {
			return time;
		}
		public String getType() {
			return type;
		}
		public void setType(String type) {
			this.type = type;
		}
		public Object getData() {
			return data;
		}
		@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.EXTERNAL_PROPERTY, property = "type")
		@JsonTypeIdResolver(ChildBaseByParentTypeResolver.class)
		public void setData(Object data) {
			this.data = data;
		}
	}

When I launch the the two deserialization, I have the next results

content = {"time":345,"type":"track","data":{"data-internal":"toto"}}
MyJson result
time=345
type=track
data=class com.navalgroup.sdms.ac.model.impl.test.TestDeserialisation$MyData ; [[data-internal=toto]]

MyJson2 result
time=345
type=null
data=null

When I've got the sources and I've tried to debug the unexpected MyJson2 result, I've lost myself in BeanDeserializer.deserializeUsingPropertyBasedWithExternalTypeId. The Json datas seem to be put in TokenBuffer which doesn't seem used.

I attached a fully executed Java File with my test classes.
TestDeserialisation.zip

Thanks for your attention

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions