title: When is a JsonNode instance null?
body: <p>Consider the following Java class definition.</p>
  
  <p>CrudOperation.java:</p>
  
  <pre><code>package com.cyberfront.test.json.nll.demonstration;
  
  import com.fasterxml.jackson.annotation.JsonCreator;
  import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
  import com.fasterxml.jackson.annotation.JsonInclude;
  import com.fasterxml.jackson.annotation.JsonProperty;
  import com.fasterxml.jackson.annotation.JsonTypeInfo;
  import com.fasterxml.jackson.databind.JsonNode;
  
  @JsonIgnoreProperties(ignoreUnknown = true)
  @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY)
  @JsonInclude(JsonInclude.Include.NON_NULL)
  public class CrudOperation{
      public enum Type {CREATE,UPDATE,DELETE,READ}
      private final Type type;
      private final JsonNode op;
  
      public CrudOperation(Type type) { this(type, null); }
      public CrudOperation(JsonNode op) { this(Type.UPDATE, op); }
  
      @JsonCreator
      public CrudOperation(@JsonProperty("type") Type type, @JsonProperty("op") JsonNode op) {
          this.type = type;
          this.op = op;
  
          boolean isUpdate = Type.UPDATE.equals(this.getType());
          boolean isNotNull = null == this.getOp();
          boolean isValid = isUpdate ^ isNotNull;
  
          if (!isValid) {
              System.out.println(" isUpdate: " + String.valueOf(isUpdate));
              System.out.println("isNotNull: " + String.valueOf(isNotNull));
              System.out.println("  isValid: " + String.valueOf(isValid));
  
              throw new IllegalArgumentException("Operation Failed Validation: " + this.toString());
          }
      }
  
      @JsonProperty("type")
      public Type getType() { return this.type; };
  
      @JsonProperty("op")
      public JsonNode getOp() { return this.op; }
  
      public static &lt;T&gt; String nullCheck(T val) { return null == val ? "null" : val.toString(); }
  
      public static String toString(Type type, JsonNode op) {
          return "{\"type\":\"" + nullCheck(type) + "\",\"op\":" + nullCheck(op) + "}";
      }
  
      @Override
      public String toString() { return toString(this.getType(), this.getOp()); }
  }
  </code></pre>
  
  <p>In this class, the constructor with the <code>@JsonCreator</code> annotation performs validation to ensure there is a non-null <code>JsonNode</code> argument <code>op</code> exactly when the <code>type</code> argument has the value <code>Type.UPDATE</code>.  That is, when <code>type</code> has value <code>Type.UPDATE</code>, <code>op</code> should be non-null.  If <code>type</code> has any other value, <code>op</code> should be null.</p>
  
  <p>Next consider the class below.</p>
  
  <p>Main.java:</p>
  
  <pre><code>package com.cyberfront.test.json.nll.demonstration;
  
  import com.cyberfront.test.json.nll.demonstration.CrudOperation.Type;
  import com.fasterxml.jackson.core.JsonProcessingException;
  import com.fasterxml.jackson.databind.JsonNode;
  import com.fasterxml.jackson.databind.ObjectMapper;
  
  public class Main {
  
      private static ObjectMapper mapper = new ObjectMapper();
  
      public static void main(String[] args) {
          CrudOperation createObject = new CrudOperation(Type.CREATE);
          System.out.println("Initial value: " + createObject.toString());
  
          JsonNode createDocument = mapper.valueToTree(createObject);
          System.out.println("Document value: " + createDocument.toString());
  
          CrudOperation reconstructedObject = null;
          try {
              reconstructedObject = mapper.treeToValue(createDocument, CrudOperation.class);
          } catch (JsonProcessingException e) {
              System.out.println(e);
          }
  
          System.out.println("Reconstructed: " + CrudOperation.nullCheck(reconstructedObject));
      }
  }
  </code></pre>
  
  <p>This is used to test the creation of a <code>CrudOperation</code> instance with operation type value of <code>Type.CREATE</code>, which means <code>op</code> should be null.  Yet, this produces the following output:</p>
  
  <pre><code>Initial value: {"type":"CREATE","op":null}
  Document value: {"@type":"CrudOperation","type":"CREATE"}
   isUpdate: false
  isNotNull: false
    isValid: false
  com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of com.cyberfront.test.json.nll.demonstration.CrudOperation, problem: Operation Failed Validation: {"type":"CREATE","op":null}
   at [Source: N/A; line: -1, column: -1]
  Reconstructed: null
  </code></pre>
  
  <p>The initial <code>CrudOperation</code> instantiation is validated, and the conversion of that instance to a <code>JsonNode</code> instance also works properly.  The problem occurs when attempting to reconstitute the <code>CrudOperation</code> instance from the <code>JsonNode</code> derived from the original.  For some reason, the value of <code>op</code> displays as <code>null</code>, but the test for equality with null fails, which in turn causes the <code>CrudOperation</code> validation to fail.</p>
  
  <p>Why is happening and how can it be resolved?</p>