In fasterxml, after deserialization json, if enum is first property in class, other fields are null












3














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"
}
}









share|improve this question



























    3














    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"
    }
    }









    share|improve this question

























      3












      3








      3


      1





      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"
      }
      }









      share|improve this question













      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






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 18 '18 at 8:08









      DavidDavid

      1,3541720




      1,3541720
























          1 Answer
          1






          active

          oldest

          votes


















          1














          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());
          }





          share|improve this answer





















            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
            });


            }
            });














            draft saved

            draft discarded


















            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









            1














            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());
            }





            share|improve this answer


























              1














              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());
              }





              share|improve this answer
























                1












                1








                1






                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());
                }





                share|improve this answer












                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());
                }






                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Nov 18 '18 at 17:49









                Sotirios DelimanolisSotirios Delimanolis

                208k39477568




                208k39477568






























                    draft saved

                    draft discarded




















































                    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.




                    draft saved


                    draft discarded














                    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





















































                    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







                    Popular posts from this blog

                    Biblatex bibliography style without URLs when DOI exists (in Overleaf with Zotero bibliography)

                    ComboBox Display Member on multiple fields

                    Is it possible to collect Nectar points via Trainline?