0

There is an abstract class Product and another class SomeProduct which extends Product.

Product:

@JsonTypeInfo
(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.PROPERTY,
property = "type"
)
@JsonSubTypes
({
   @JsonSubTypes.Type(value = SomeProduct.class, name = Product.PRODUCT_TYPE_SOME)
})
public abstract class Product
{
    static final String PRODUCT_TYPE_SOME = "some_product";
}

SomeProduct:

public class SomeProduct extends Product
{
    @JsonProperty("status")
    @JsonSerialize(include =  JsonSerialize.Inclusion.NON_DEFAULT)
    private int status;

    public int getStatus()
    {
        return status;
    }

    public void setStatus(int status)
    {
        this.status = status;
    }
}

There will be more classes (different products) which will extend Product.

When I serialize it using ObjectMapper,

ObjectMapper mapper = new ObjectMapper();

Product p = new SomeProduct();
String json = mapper.writeValueAsString(p);

this is the output:

{"type":"some_product"}

Now, when I try to deserialize it back,

Product x = mapper.convertValue(json, Product.class);

this exception is thrown:

java.lang.IllegalArgumentException: Unexpected token (VALUE_STRING), expected FIELD_NAME: missing property 'type' that is to contain type id (for class com.shubham.model.Product) at [Source: N/A; line: -1, column: -1]

What am I doing wrong here ? I've looked on SO and found a question where defaultImpl was used in JsonTypeInfo. But I can't deserialize the json back to a "Default Impl" since the JSON will always be valid for a specific implementation.

Using Jackson 2.4.3

Shubham
  • 780
  • 3
  • 13
  • 32
  • 2
    Could this be the issue? http://stackoverflow.com/a/14228184/4793951 – Zircon Sep 19 '16 at 13:44
  • @Zircon As mentioned in the code snippet, I've only specified "JsonTypeInfo.Id.NAME". Also, "JsonTypeInfo" is set only on the base class, and not in the subclasses. – Shubham Sep 19 '16 at 13:51

1 Answers1

3

You are wrongly using mapper.convertValue(json, Product.class);. You should use: mapper.readValue(json, Product.class);

convertValue use:

Convenience method for doing two-step conversion from given value, into instance of given value type, if (but only if!) conversion is needed. If given value is already of requested type, value is returned as is.

Franjavi
  • 647
  • 4
  • 14