Skip to content

When using type id with As.EXTERNAL_PROPERTY together with @JsonValue inside type the serialiser omits external type id field from result when @JsonValue value is null #3547

Description

@aurimasniekis

Describe the bug

When using type id with As.EXTERNAL_PROPERTY together with @jsonvalue inside type the serialiser omits external type id field from result when @jsonvalue value is null.

Version information
2.13.3

To Reproduce

package org.example;

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.As;
import com.fasterxml.jackson.annotation.JsonTypeInfo.Id;
import com.fasterxml.jackson.annotation.JsonValue;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

public class Main {
  public static interface GenericType {
    String getValue();
    void setValue(String value);
  }

  public static abstract class AbstractGenericType implements GenericType
  {
    protected String value;
    public AbstractGenericType() {}
    public AbstractGenericType(String value) {this.value = value;}
    @Override @JsonValue public String getValue() {return value;}
    @Override @JsonValue public void setValue(String value) {this.value = value;}
  }

  public static class FooType extends AbstractGenericType {
    public FooType() {super();}
    public FooType(String value) {super(value);}
  }
  public static class Container {
    @JsonTypeInfo(use = Id.MINIMAL_CLASS, include = As.EXTERNAL_PROPERTY, property = "type", visible = true)
    @JsonSubTypes(value = {@Type(value = FooType.class)})
    protected GenericType value;

    public GenericType getValue() { return value; }
    public void setValue(GenericType value) { this.value = value; }
  }

  public static void main(String[] args) throws JsonProcessingException {
    var om = new ObjectMapper();

    var container = new Container();

    System.out.println(om.writeValueAsString(container)); // {"value":null}
    // Its fine as container::value == null so external type id field is missing

    container.setValue(new FooType());

    System.out.println(om.writeValueAsString(container)); // {"value":null}
    // Its not fine as container::value != null, external type id field should be set ".Main$FooType" value

    container.setValue(new FooType("foobar"));

    System.out.println(om.writeValueAsString(container)); // {"value":"foobar","type":".Main$FooType"}
    // Now external type id field is present
  }
}

Expected behavior

Expected that external type id field should be present with type id value when type is not null.

P.S. It would be also great if it was possible to still include external type id field with for e.g. null value when type is null.

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

    3.2polymorphic-handlingProblem with polymorphic type handling (`@JsonTypeInfo`, Default Typing)

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions