Skip to content

Deserialization of generic container (of Record type) using EXTERNAL_PROPERTY fails for "natural" types (boolean/long/String/double) because type information is missing #3786

Description

@alwins0n

Describe the bug
Use case is serializing and deserializing a generic container which uses the type info in the container to deserialize the content.
In the case of primitive boxed types (Integer, String) no type information is writte to the output. While this is excepted behaviour the dual operation fails because jackson complains that this very type information is missing.

Version information
Testet on multiple. Latest was 2.14.1

To Reproduce
Minimal example test

public class JacksonTest {

  @Test
  public void serDeser() throws Exception {
    var mapper = new ObjectMapper().registerModule(new ParameterNamesModule());

    var strContainer = new Container<>(1, "Hello");
    var myContainer = new Container<>(1, new MyObject("foo", "bar"));

    var strContainerJson = mapper.writeValueAsString(strContainer);
    var myContainerJson = mapper.writeValueAsString(myContainer);

    System.out.println(strContainerJson);
    System.out.println(myContainerJson);

    // this works with the correct type in memory
    var myContainerDeser = mapper.readValue(myContainerJson, new TypeReference<Container<?>>() {
    });
    // this fails with an exception
    var strContainerDeser = mapper.readValue(strContainerJson, new TypeReference<Container<?>>() {
    });
  }


  record Container<T>(
    int id,
    @JsonTypeInfo(
      use = JsonTypeInfo.Id.CLASS,
      include = JsonTypeInfo.As.EXTERNAL_PROPERTY,
      property = "type"
    )
    T value
  ) {
    @JsonCreator
    Container {
    }
  }

  record MyObject(
    String foo,
    String bar
  ) {
    @JsonCreator
    MyObject {
    }
  }

}

where the last line of the test fails with an exception and the full output is

{"id":1,"value":"Hello"}
{"id":1,"value":{"foo":"foo","bar":"bar"},"type":"JacksonTest$MyObject"}

Missing external type id property 'type'
 at [Source: (String)"{"id":1,"value":"Hello"}"; line: 1, column: 24] (through reference chain: JacksonTest$Container["value"])
com.fasterxml.jackson.databind.exc.MismatchedInputException: Missing external type id property 'type'
 at [Source: (String)"{"id":1,"value":"Hello"}"; line: 1, column: 24] (through reference chain: JacksonTest$Container["value"])
	at app//com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:63)
	at app//com.fasterxml.jackson.databind.DeserializationContext.reportPropertyInputMismatch(DeserializationContext.java:1781)
	at app//com.fasterxml.jackson.databind.DeserializationContext.reportPropertyInputMismatch(DeserializationContext.java:1797)
	at app//com.fasterxml.jackson.databind.deser.impl.ExternalTypeHandler.complete(ExternalTypeHandler.java:283)
	at app//com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeUsingPropertyBasedWithExternalTypeId(BeanDeserializer.java:1100)
	at app//com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeWithExternalTypeId(BeanDeserializer.java:941)
	at app//com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:350)
	at app//com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:185)
	at app//com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:323)
	at app//com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4730)
	at app//com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3677)
	at app//com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3645)
	at app//JacksonTest.serDeser(JacksonTest.java:25)

Expected behavior
No type information on serialization for built-in primitive json mappable types ( String, Boolean, Integer ), but no type information should be required for deserialisation of these types using EXTERNAL_PROPERTY

Additional context
I searched the issues for something similar but could not find anything. Sorry if this is a duplicate

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    RecordIssue related to JDK17 java.lang.Record supporthas-failing-testIndicates that there exists a test case (under `failing/`) to reproduce the issue

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions