-
-
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
External property is not deserialized #999
Comments
The problem is that by default Jackson considers type information metadata, which is not exposed to serializer or deserializer, but handled by itself. This simplifies handling for most cases. Another potential problem with code is the use of generic root value (with type parameter), but not using
which would pass paramaterization. |
I want Unfortunately neither adding Edit: I added your proposed fixes to the repo, the link to the commit: |
Odd. |
Actually, I suspect the problem may be with use of constructor, as opposed to field or setter. Test case should help figure out what is going on. |
@cowtowncoder yep, using setters instead of constructor did the trick. However, it seems to me that external properties should be usable with constructors too, shouldn't they? Is it a bug? |
@crew4ok Ideally, yes, that should work. It can be considered a bug, although my concern is that it could also become an implementation imposed limit, constraint. It is a flaw at this point I think. The challenge, technically, is that use of constructors is complicated (compared to using setters/fields of an object) due to additional buffering: instead of being able to recursively deserialize values, one by one, it is often necessary to buffer everything that is passed via constructor, until actual type is found, to know what to construct, how. So: yes, looks like a bug. But not something that is necessarily simple to resolve. |
@cowtowncoder i see, things are complicated and i should not rely on soon resolution of the bug... Anyway, thanks for the clarifying the issue a bit. |
I was just about to file the same issue. FWIW, I have created a self-contained test class which may be a bit easier to play with than @oleksandr-oksenenko’s test project: import java.io.IOException;
import java.util.Objects;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.JsonTypeName;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
public class JacksonTest {
public static interface Payload { }
@JsonTypeName("foo")
public static class FooPayload implements Payload { }
@JsonTypeName("bar")
public static class BarPayload implements Payload { }
public static class Message<P extends Payload> {
private final String type;
@JsonTypeInfo(visible = true, use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.EXTERNAL_PROPERTY, property = "type")
@JsonSubTypes({
@JsonSubTypes.Type(FooPayload.class),
@JsonSubTypes.Type(BarPayload.class) })
private final P payload;
@JsonCreator
public Message(@JsonProperty("type") String type,
@JsonProperty("payload") P payload) {
Objects.requireNonNull(type);
// ^-- this fails since "type" is null
Objects.requireNonNull(payload);
this.type = type;
this.payload = payload;
}
// (getters omitted here)
}
public static void main(String[] args) throws IOException {
ObjectMapper objectMapper = new ObjectMapper();
Message<?> msg = objectMapper.readValue(
"{ \"type\": \"foo\", \"payload\": {} }",,
new TypeReference<Message<FooPayload>>() { });
}
} |
@cspurk Thank you for the test. Just to make sure: does this fail with 2.7.0, or just older versions? |
@cowtowncoder Yes, it fails with 2.7.0, too. |
Added the failing unit test, should help eventually resolve the issue. |
# By Tatu Saloranta (113) and others # Via Tatu Saloranta * 'master' of https://github.com/FasterXML/jackson-databind: (124 commits) Minor addition related to FasterXML#1087: resolve context type, assuming type bindings from that are expected to work. Add unit test for FasterXML#999 minor warnings cleanup Add Javadoc badge with automatic version detection Fix FasterXML#1083 Add failing test for FasterXML#1083 add a unit test to verify that Object Id works via AtomicReference too Minor javadoc improvement wrt FasterXML#1076, making `SimpleType.construct(Class)` deprecated (was not yet, for some reason, should have been) Fix FasterXML#1078 Fix FasterXML#1079 [maven-release-plugin] prepare for next development iteration [maven-release-plugin] prepare release jackson-databind-2.7.0 prepare for 2.7.0 final Fix FasterXML#1073 Try to reproduce FasterXML#1074 javadoc trimming Try to reproduce FasterXML#825 again, still passes. minor improvement to ensure base64 encoding uses configured setting Undo part of change done for StringDeserializer; caused issues with XML handling further minor cleanups to cleanup ...
Finally found time to dig deep enough and figure out why things were failing, how to fix. |
I think it's easier to show the code than explain the issue, so i prepared a test project:
https://github.com/crew4ok/jackson-databind-test
So basically the issue is that the external property, by which another's property type is deduced, after deserialization is null.
See the failing test:
https://github.com/crew4ok/jackson-databind-test/blob/master/src/test/java/jackson/ExternalIdDeserTest.java
Am i missing something?
The text was updated successfully, but these errors were encountered: