-
-
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
Deserialization fails depending on the order of deserialized objects with "Cannot construct instance (although at least one Creator exists)" #3355
Comments
It does sound like a bug, and my first guess would be it might be related to |
After some more fiddling around, I've noticed that that public class Common {
private final String property;
private final Container container;
@JsonCreator
public Common(@JsonProperty("property") final String property,
@JsonProperty("container") final Container container) {
this.property = property;
this.container = container;
}
public String getProperty() {
return property;
}
public Container getContainer() {
return container;
}
}
public class Container {
private final Common common;
@JsonCreator
public Container(@JsonProperty("common") final Common common) {
this.common = common;
}
@JsonIgnoreProperties("container")
public Common getCommon() {
return common;
}
}
public static void main(final String[] args) throws Exception {
final String objectJson = "{ \"property\": \"valueOne\" }";
final String containersJson = "{ \"common\": { \"property\": \"valueTwo\" } }";
final ObjectMapper objectMapper = new ObjectMapper();
final Common object = objectMapper.readValue(objectJson, Common.class);
final Container container = objectMapper.readValue(containersJson, Container.class); // Fails
} Also, it seems to be only an issue with the property-based creator. Adding any other creator (setters or POJOBuilder) makes the issue go away, though both are not ideal workarounds. EDIT: Updated to further simplify the case. |
Can we get any updates on this? It's fairly important for us to have this fixed soon, and we would like to avoid having to write temporary workarounds in our applications. |
@dinopraso Unfortunately I don't have time to work on this at this point in time. I hope sometimes else can help, or you figure it out. |
I've been looking though the source code for a while, and I've figured something out! This whole time, I've have the assumption that, since it is only the getter which was annotated with I am not sure whether this behaviour is expected thought? Should Either way, at least we now have a simple way to fix this in our projects. |
Yes this is also the behavior for other annotations, the best example being class Test {
private String foo;
@JsonProperty("bar")
public String getFoo() {
return foo;
}
public void setFoo(String foo) {
this.foo = foo;
}
} The property will be called You can essentially think of annotations as applying to the property (getter + setter), not the individual accessor, though there are some special rules when it comes to conflicting annotations. |
Though the issue still remains to be fixed, since the fact that a set of properties was ignored on one class shouldn't affect the deserialization of another |
The behavior about "unifying annotations" (combining) -- that annotations in one accessor are indeed applied to the "whole" logical property, regardless of which accessor had it -- is indeed 100% intended and working as defined. Having said that it sounds like there is a separate issue which is likely due to the way that |
In order to fix this issue, You may create your JsonDeserializer which will help you to convert this. I've used below snippet in order to fix my issue which works fine.
Here, Value is my class. |
If anyone has time, would be good to see if this still occurs with 2.18.2 -- good chance it's been fixed. |
Yes, still failing in 2.18 latest version. |
Describe the bug
Deserialization of a specific class becomes broken if another specific class is deserialized before it. All classes are immutable and depend on
@JsonCreator
and property-based constructors with all properties annotated correctly with@JsonProperty
.If a class
ContainerOne
is deserialized before a classContainerTwo
(see below for reference), deserialization will fail, but it you flip their order, it will work as expected.It appears that some sort of caching is handled incorrectly making the second invocation ignore the property-based creator.
Version information
Reproduced on 2.12.3 and 2.13.0
To Reproduce
Here is the minimal setup I've managed to make to reproduce this.
I have found two ways to stop this from happening, both of which are not really an option for me at this point:
@JsonIgnoreProperties("twos")
from the getter inContainerTwo
Common
mutable, with settersExpected behavior
Since this behavior is specific to the execution order and breaks seemingly unexpectedly, it appears to be a bug.
Expected behavior should be that both objects are deserialized (like they are individually) regardless of their invocation order.
Additional Information
Here is the full stack trace of the exception that happens
The text was updated successfully, but these errors were encountered: