In fasterxml, after deserialization json, if enum is first property in class, other fields are null
In fasterxml, after deserialization json, if enum (with JsonFormat.Shape.OBJECT) is first property in class, other fields are null.
Why enum should be last declared property in class to deserialize other fields properly?
Maybe this could be a bug in fasterxml?
Example class MyClass
:
public class MyClass {
// >>>
// >>> element field is null after deserialization
// >>>
private MyEnum option; // first
private String element; // --> null
// >>>
// >>> correctly deserialized if enum is last in order
// >>>
// private String element; // --> "elem"
// private MyEnum option; // last
public MyEnum getOption() {
return option;
}
public void setOption(MyEnum option) {
this.option = option;
}
public String getElement() {
return element;
}
public void setElement(String element) {
this.element = element;
}
}
Example enum MyEnum
:
@JsonFormat(shape = JsonFormat.Shape.OBJECT)
public enum MyEnum {
FIRST;
@JsonProperty
public String getOption() {
return name();
}
@JsonCreator
public static MyEnum forValue(String option) {
return FIRST;
}
}
Example main test class Main
:
public class Main {
public static void main(String args) throws IOException {
ObjectMapper mapper = new com.fasterxml.jackson.databind.ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
MyClass myClass = new MyClass();
myClass.setElement("elem");
myClass.setOption(MyEnum.FIRST);
String serialized = mapper.writer().withDefaultPrettyPrinter().writeValueAsString(myClass);
System.out.println(String.format("serialized - %s", serialized));
MyClass deserialized = mapper.readValue(serialized, MyClass.class);
String deserializedResult = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(deserialized);
System.out.println(String.format("deserialized - %s", deserializedResult));
}
}
Output showing field is null
after deserialization:
serialized - {
"option" : {
"option" : "FIRST"
},
"element" : "elem"
}
deserialized - {
"option" : {
"option" : "FIRST"
},
"element" : null
}
Output after fixing order (uncommented lines in MyClass
):
serialized - {
"element" : "elem",
"option" : {
"option" : "FIRST"
}
}
deserialized - {
"element" : "elem",
"option" : {
"option" : "FIRST"
}
}
java enums jackson deserialization fasterxml
add a comment |
In fasterxml, after deserialization json, if enum (with JsonFormat.Shape.OBJECT) is first property in class, other fields are null.
Why enum should be last declared property in class to deserialize other fields properly?
Maybe this could be a bug in fasterxml?
Example class MyClass
:
public class MyClass {
// >>>
// >>> element field is null after deserialization
// >>>
private MyEnum option; // first
private String element; // --> null
// >>>
// >>> correctly deserialized if enum is last in order
// >>>
// private String element; // --> "elem"
// private MyEnum option; // last
public MyEnum getOption() {
return option;
}
public void setOption(MyEnum option) {
this.option = option;
}
public String getElement() {
return element;
}
public void setElement(String element) {
this.element = element;
}
}
Example enum MyEnum
:
@JsonFormat(shape = JsonFormat.Shape.OBJECT)
public enum MyEnum {
FIRST;
@JsonProperty
public String getOption() {
return name();
}
@JsonCreator
public static MyEnum forValue(String option) {
return FIRST;
}
}
Example main test class Main
:
public class Main {
public static void main(String args) throws IOException {
ObjectMapper mapper = new com.fasterxml.jackson.databind.ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
MyClass myClass = new MyClass();
myClass.setElement("elem");
myClass.setOption(MyEnum.FIRST);
String serialized = mapper.writer().withDefaultPrettyPrinter().writeValueAsString(myClass);
System.out.println(String.format("serialized - %s", serialized));
MyClass deserialized = mapper.readValue(serialized, MyClass.class);
String deserializedResult = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(deserialized);
System.out.println(String.format("deserialized - %s", deserializedResult));
}
}
Output showing field is null
after deserialization:
serialized - {
"option" : {
"option" : "FIRST"
},
"element" : "elem"
}
deserialized - {
"option" : {
"option" : "FIRST"
},
"element" : null
}
Output after fixing order (uncommented lines in MyClass
):
serialized - {
"element" : "elem",
"option" : {
"option" : "FIRST"
}
}
deserialized - {
"element" : "elem",
"option" : {
"option" : "FIRST"
}
}
java enums jackson deserialization fasterxml
add a comment |
In fasterxml, after deserialization json, if enum (with JsonFormat.Shape.OBJECT) is first property in class, other fields are null.
Why enum should be last declared property in class to deserialize other fields properly?
Maybe this could be a bug in fasterxml?
Example class MyClass
:
public class MyClass {
// >>>
// >>> element field is null after deserialization
// >>>
private MyEnum option; // first
private String element; // --> null
// >>>
// >>> correctly deserialized if enum is last in order
// >>>
// private String element; // --> "elem"
// private MyEnum option; // last
public MyEnum getOption() {
return option;
}
public void setOption(MyEnum option) {
this.option = option;
}
public String getElement() {
return element;
}
public void setElement(String element) {
this.element = element;
}
}
Example enum MyEnum
:
@JsonFormat(shape = JsonFormat.Shape.OBJECT)
public enum MyEnum {
FIRST;
@JsonProperty
public String getOption() {
return name();
}
@JsonCreator
public static MyEnum forValue(String option) {
return FIRST;
}
}
Example main test class Main
:
public class Main {
public static void main(String args) throws IOException {
ObjectMapper mapper = new com.fasterxml.jackson.databind.ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
MyClass myClass = new MyClass();
myClass.setElement("elem");
myClass.setOption(MyEnum.FIRST);
String serialized = mapper.writer().withDefaultPrettyPrinter().writeValueAsString(myClass);
System.out.println(String.format("serialized - %s", serialized));
MyClass deserialized = mapper.readValue(serialized, MyClass.class);
String deserializedResult = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(deserialized);
System.out.println(String.format("deserialized - %s", deserializedResult));
}
}
Output showing field is null
after deserialization:
serialized - {
"option" : {
"option" : "FIRST"
},
"element" : "elem"
}
deserialized - {
"option" : {
"option" : "FIRST"
},
"element" : null
}
Output after fixing order (uncommented lines in MyClass
):
serialized - {
"element" : "elem",
"option" : {
"option" : "FIRST"
}
}
deserialized - {
"element" : "elem",
"option" : {
"option" : "FIRST"
}
}
java enums jackson deserialization fasterxml
In fasterxml, after deserialization json, if enum (with JsonFormat.Shape.OBJECT) is first property in class, other fields are null.
Why enum should be last declared property in class to deserialize other fields properly?
Maybe this could be a bug in fasterxml?
Example class MyClass
:
public class MyClass {
// >>>
// >>> element field is null after deserialization
// >>>
private MyEnum option; // first
private String element; // --> null
// >>>
// >>> correctly deserialized if enum is last in order
// >>>
// private String element; // --> "elem"
// private MyEnum option; // last
public MyEnum getOption() {
return option;
}
public void setOption(MyEnum option) {
this.option = option;
}
public String getElement() {
return element;
}
public void setElement(String element) {
this.element = element;
}
}
Example enum MyEnum
:
@JsonFormat(shape = JsonFormat.Shape.OBJECT)
public enum MyEnum {
FIRST;
@JsonProperty
public String getOption() {
return name();
}
@JsonCreator
public static MyEnum forValue(String option) {
return FIRST;
}
}
Example main test class Main
:
public class Main {
public static void main(String args) throws IOException {
ObjectMapper mapper = new com.fasterxml.jackson.databind.ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
MyClass myClass = new MyClass();
myClass.setElement("elem");
myClass.setOption(MyEnum.FIRST);
String serialized = mapper.writer().withDefaultPrettyPrinter().writeValueAsString(myClass);
System.out.println(String.format("serialized - %s", serialized));
MyClass deserialized = mapper.readValue(serialized, MyClass.class);
String deserializedResult = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(deserialized);
System.out.println(String.format("deserialized - %s", deserializedResult));
}
}
Output showing field is null
after deserialization:
serialized - {
"option" : {
"option" : "FIRST"
},
"element" : "elem"
}
deserialized - {
"option" : {
"option" : "FIRST"
},
"element" : null
}
Output after fixing order (uncommented lines in MyClass
):
serialized - {
"element" : "elem",
"option" : {
"option" : "FIRST"
}
}
deserialized - {
"element" : "elem",
"option" : {
"option" : "FIRST"
}
}
java enums jackson deserialization fasterxml
java enums jackson deserialization fasterxml
asked Nov 18 '18 at 8:08
DavidDavid
1,3541720
1,3541720
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
I couldn't tell you if it's a bug, you can debug and step through the code to understand how Jackson "fails" in this scenario. Your use of FAIL_ON_UNKNOWN_PROPERTIES
hides the problem, which is using String
as the parameter type of your forValue
factory method. In short, Jackson gets "stuck" in traversing the tokens of the JSON content.
To fix it properly, ie. not rely on order, you have a couple of options. First, get rid of the JsonFormat.Shape.OBJECT
shape for serializing the enum type and its corresponding @JsonCreator
. The default serialization/deserialization for an enum is to use its name anyway.
Second, if you really want to keep the OBJECT shape, you'll need to change your @JsonCreator
method to receive an ObjectNode
, since that's what the JSON contains, not a String
. From there, you can perform the deserialization yourself (assuming you have more enum constants)
@JsonCreator
public static MyEnum forValue(ObjectNode object) {
return MyEnum.valueOf(object.get("option").asText());
}
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53358986%2fin-fasterxml-after-deserialization-json-if-enum-is-first-property-in-class-ot%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
I couldn't tell you if it's a bug, you can debug and step through the code to understand how Jackson "fails" in this scenario. Your use of FAIL_ON_UNKNOWN_PROPERTIES
hides the problem, which is using String
as the parameter type of your forValue
factory method. In short, Jackson gets "stuck" in traversing the tokens of the JSON content.
To fix it properly, ie. not rely on order, you have a couple of options. First, get rid of the JsonFormat.Shape.OBJECT
shape for serializing the enum type and its corresponding @JsonCreator
. The default serialization/deserialization for an enum is to use its name anyway.
Second, if you really want to keep the OBJECT shape, you'll need to change your @JsonCreator
method to receive an ObjectNode
, since that's what the JSON contains, not a String
. From there, you can perform the deserialization yourself (assuming you have more enum constants)
@JsonCreator
public static MyEnum forValue(ObjectNode object) {
return MyEnum.valueOf(object.get("option").asText());
}
add a comment |
I couldn't tell you if it's a bug, you can debug and step through the code to understand how Jackson "fails" in this scenario. Your use of FAIL_ON_UNKNOWN_PROPERTIES
hides the problem, which is using String
as the parameter type of your forValue
factory method. In short, Jackson gets "stuck" in traversing the tokens of the JSON content.
To fix it properly, ie. not rely on order, you have a couple of options. First, get rid of the JsonFormat.Shape.OBJECT
shape for serializing the enum type and its corresponding @JsonCreator
. The default serialization/deserialization for an enum is to use its name anyway.
Second, if you really want to keep the OBJECT shape, you'll need to change your @JsonCreator
method to receive an ObjectNode
, since that's what the JSON contains, not a String
. From there, you can perform the deserialization yourself (assuming you have more enum constants)
@JsonCreator
public static MyEnum forValue(ObjectNode object) {
return MyEnum.valueOf(object.get("option").asText());
}
add a comment |
I couldn't tell you if it's a bug, you can debug and step through the code to understand how Jackson "fails" in this scenario. Your use of FAIL_ON_UNKNOWN_PROPERTIES
hides the problem, which is using String
as the parameter type of your forValue
factory method. In short, Jackson gets "stuck" in traversing the tokens of the JSON content.
To fix it properly, ie. not rely on order, you have a couple of options. First, get rid of the JsonFormat.Shape.OBJECT
shape for serializing the enum type and its corresponding @JsonCreator
. The default serialization/deserialization for an enum is to use its name anyway.
Second, if you really want to keep the OBJECT shape, you'll need to change your @JsonCreator
method to receive an ObjectNode
, since that's what the JSON contains, not a String
. From there, you can perform the deserialization yourself (assuming you have more enum constants)
@JsonCreator
public static MyEnum forValue(ObjectNode object) {
return MyEnum.valueOf(object.get("option").asText());
}
I couldn't tell you if it's a bug, you can debug and step through the code to understand how Jackson "fails" in this scenario. Your use of FAIL_ON_UNKNOWN_PROPERTIES
hides the problem, which is using String
as the parameter type of your forValue
factory method. In short, Jackson gets "stuck" in traversing the tokens of the JSON content.
To fix it properly, ie. not rely on order, you have a couple of options. First, get rid of the JsonFormat.Shape.OBJECT
shape for serializing the enum type and its corresponding @JsonCreator
. The default serialization/deserialization for an enum is to use its name anyway.
Second, if you really want to keep the OBJECT shape, you'll need to change your @JsonCreator
method to receive an ObjectNode
, since that's what the JSON contains, not a String
. From there, you can perform the deserialization yourself (assuming you have more enum constants)
@JsonCreator
public static MyEnum forValue(ObjectNode object) {
return MyEnum.valueOf(object.get("option").asText());
}
answered Nov 18 '18 at 17:49
Sotirios DelimanolisSotirios Delimanolis
208k39477568
208k39477568
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53358986%2fin-fasterxml-after-deserialization-json-if-enum-is-first-property-in-class-ot%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown