-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
Deserializing polymorphic type with defaultImpl
sets type ID to null
#3313
Comments
No, I don't think this was intentional change. However, I am not sure about the test -- does it default to inclusion of Note that |
Yes, it's using the default of
The issue is reproducible with both, |
Ah. After quickly reading this again, I am not sure this is a bug -- if input has |
@cowtowncoder I'm fine with either outcome, either reverting to the old behavior with regards to the |
I think I stumbled across the same (or at least similar) issue. With Jackson 2.12.5 this was working fine with @JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.PROPERTY,
property = "type"
)
@JsonTypeIdResolver(MyClassType.Resolver.class)
public abstract class MyClass<T> {
protected MyClass(String type) {
this.type = type;
}
private String type;
public String getType() { return type; }
public void setType(String type) { this.type = type; }
}
public class MyClassType {
private static final Map<String, Class<? extends MyClass<?>>> typeMap = ...;
private static final Class<? extends MyClass<?>> defaultValue = ...;
public static class Resolver extends TypeIdResolverBase {
@Override
public String idFromValue(Object value) {
return idFromValueAndType(value, null);
}
@Override
public String idFromValueAndType(Object value, Class<?> suggestedType) {
return ((MyClass<?>) value).getType();
}
@Override
public JavaType typeFromId(DatabindContext context, String id) {
return TypeFactory.defaultInstance().constructType(typeMap.getOrDefault(id, defaultValue));
}
@Override
public Id getMechanism() {
return Id.NAME;
}
}
} And with Jackson 2.13.0 the overridden Resolver methods won't get called, but instead I get:
@joschi Do you have a workaround to convince Jackson 2.13.0 to allow null values? |
@benneq We downgraded to Jackson 2.12.5 until we have time to work around the issue in our own code or the old behavior has been restored in a Jackson 2.13.x patch release. |
Quick note: my definite leaning is to document this (contributions for verbiage would be appreciated but I'll try to add something), and not change behavior. I updated 2.13 release notes with an entry wrt https://github.com/FasterXML/jackson/wiki/Jackson-Release-2.13 |
Hi @cowtowncoder,
Are you sure this was a wise decision to accept this as the new expected behavior? Because for me, this is very counter intuitive. Especially by taking @joschi 's provided example: static class TypeA extends BaseClass {
static final String TYPE = "A"; // <<< this is FINAL
String customA;
@JsonCreator
TypeA(@JsonProperty("custom") String custom) {
super(TYPE); // <<< explicitly setting the type for a FINAL field in constructor
this.customA = custom;
}
} if the use of e.g. the following in the code, which was completely uncritical before, but now causes an NPE or unexpected behaviour out of a sudden: if (obj.getType().equals(TypeA.TYPE)) { ... } // NPE with 2.13.0+
if (TypeA.TYPE.equals(obj.getType())) { ... } // evaluates to false in 2.13.0+ Just by reading the code, never on earth would I expect that
In my point of view, this change is a quite significant breaking change. |
Describe the bug
Starting with Jackson Databind 2.13.0, deserializing a polymorphic type with a default implementation (
JsonTypeInfo.defaultImpl
) and an explicitnull
for the type ID will produce an instance of the concrete type in which the type ID isnull
instead of a value provided during construction (in its constructor/@JsonCreator
method).In Jackson Databind 2.12.5 and earlier, this produced an instance of the concrete type in which the type ID field had the value assigned in the constructor/
@JsonCreator
method.We're using Jackson Databind to deserialize user-provided input, so unfortunately we cannot prevent them from sending JSON payloads with
null
in the type ID field, even if it isn't valid in the first place.Version information
Working on Jackson Databind 2.12.5.
Failing on Jackson Databind 2.13.0.
To Reproduce
Expected behavior
With Jackson Databind 2.12.5, the unit test succeeds while with Jackson Databind 2.13.0 it fails because
object.type
isnull
instead of using the value of the default implementationTypeA
("A"):Additional context
I suspect this behavior was changed in the context of #3271 and 32eee1b.
If the new behavior is intentional, it should be mentioned in the release notes for Jackson 2.13.0 as a breaking change.
The text was updated successfully, but these errors were encountered: