title: Deserialization of generated sub-class results in the parent object
body: <p><em>Versions: Swagger-codegen (v3): 3.0.11 | Jackson: 2.9.8</em></p>
  
  <p>I currently generate my classes from a <code>swagger.yaml</code> file (indentation may differ due to double copy-paste):</p>
  
  <pre><code>---
  swagger: "2.0"
  info:
    description: "servicename"
    version: "1.0"
    title: "servicename"
  schemes:
    - "http"
    - "https"
  paths:
  
  definitions:
    Notification:
      type: "object"
      discriminator: "typeOfNotification"
      properties:
        typeOfNotification:
          description: "Type of notification"
          enum:
            - "EMAIL"
            - "SMS"
          default: "EMAIL"
    EmailNotification:
      allOf:
      - $ref: "#/definitions/Notification"
      - type: "object"
        properties:
          name:
            type: "string"
            example: "Name of reciever"
            description: "Name of the receiver"
          emailAddress:
            type: "string"
            example: "info@stackoverflow.com"
            description: "Email address of the receiver"
  </code></pre>
  
  <p>Which generates two classes:</p>
  
  <p>Notification.java</p>
  
  <pre><code>package nl.test;
  
  import java.util.Objects;
  import java.util.Arrays;
  import com.google.gson.TypeAdapter;
  import com.google.gson.annotations.JsonAdapter;
  import com.google.gson.annotations.SerializedName;
  import com.google.gson.stream.JsonReader;
  import com.google.gson.stream.JsonWriter;
  import io.swagger.v3.oas.annotations.media.Schema;
  import java.io.IOException;
  /**
   * Notification
   */
  
  @javax.annotation.Generated(value = "io.swagger.codegen.v3.generators.java.JavaClientCodegen", date = "2019-09-26T16:01:12.401+02:00[Europe/Amsterdam]")
  public abstract class Notification {
    /**
     * Type of notification
     */
    @JsonAdapter(TypeOfNotificationEnum.Adapter.class)
    public enum TypeOfNotificationEnum {
      EMAIL("EMAIL"),
      SMS("SMS");
  
      private String value;
  
      TypeOfNotificationEnum(String value) {
        this.value = value;
      }
      public String getValue() {
        return value;
      }
  
      @Override
      public String toString() {
        return String.valueOf(value);
      }
      public static TypeOfNotificationEnum fromValue(String text) {
        for (TypeOfNotificationEnum b : TypeOfNotificationEnum.values()) {
          if (String.valueOf(b.value).equals(text)) {
            return b;
          }
        }
        return null;
      }
      public static class Adapter extends TypeAdapter&lt;TypeOfNotificationEnum&gt; {
        @Override
        public void write(final JsonWriter jsonWriter, final TypeOfNotificationEnum enumeration) throws IOException {
          jsonWriter.value(enumeration.getValue());
        }
  
        @Override
        public TypeOfNotificationEnum read(final JsonReader jsonReader) throws IOException {
          String value = jsonReader.nextString();
          return TypeOfNotificationEnum.fromValue(String.valueOf(value));
        }
      }
    }  @SerializedName("typeOfNotification")
    private TypeOfNotificationEnum typeOfNotification = null;
  
    public Notification typeOfNotification(TypeOfNotificationEnum typeOfNotification) {
      this.typeOfNotification = typeOfNotification;
      return this;
    }
  
  
    @Schema(description = "Type of notification")
    public TypeOfNotificationEnum getTypeOfNotification() {
      return typeOfNotification;
    }
  
    public void setTypeOfNotification(TypeOfNotificationEnum typeOfNotification) {
      this.typeOfNotification = typeOfNotification;
    }
  
  
    @Override
    public boolean equals(java.lang.Object o) {
      if (this == o) {
        return true;
      }
      if (o == null || getClass() != o.getClass()) {
        return false;
      }
      Notification notification = (Notification) o;
      return Objects.equals(this.typeOfNotification, notification.typeOfNotification);
    }
  
    @Override
    public int hashCode() {
      return Objects.hash(typeOfNotification);
    }
  }
  </code></pre>
  
  <p>And the EmailNotification:</p>
  
  <pre><code>package nl.test;
  
  import java.util.Objects;
  import java.util.Arrays;
  import com.google.gson.TypeAdapter;
  import com.google.gson.annotations.JsonAdapter;
  import com.google.gson.annotations.SerializedName;
  import com.google.gson.stream.JsonReader;
  import com.google.gson.stream.JsonWriter;
  import io.swagger.v3.oas.annotations.media.Schema;
  import java.io.IOException;
  import nl.test.Notification;
  /**
   * EmailNotification
   */
  
  @javax.annotation.Generated(value = "io.swagger.codegen.v3.generators.java.JavaClientCodegen", date = "2019-09-26T16:01:12.401+02:00[Europe/Amsterdam]")
  public class EmailNotification extends Notification {
    @SerializedName("name")
    private String name = null;
  
    @SerializedName("emailAddress")
    private String emailAddress = null;
  
    public EmailNotification name(String name) {
      this.name = name;
      return this;
    }
  
     /**
     * Name of the receiver
     * @return name
    **/
    @Schema(example = "Name of receiver", description = "Name of the receiver")
    public String getName() {
      return name;
    }
  
    public void setName(String name) {
      this.name = name;
    }
  
    public EmailNotification emailAddress(String emailAddress) {
      this.emailAddress = emailAddress;
      return this;
    }
  
     /**
     * Email address of the receiver
     * @return emailAddress
    **/
    @Schema(example = "test@stackoverflow.com", description = "Email address of the receiver")
    public String getEmailAddress() {
      return emailAddress;
    }
  
    public void setEmailAddress(String emailAddress) {
      this.emailAddress = emailAddress;
    }
  
  
    @Override
    public boolean equals(java.lang.Object o) {
      if (this == o) {
        return true;
      }
      if (o == null || getClass() != o.getClass()) {
        return false;
      }
       EmailNotification = (EmailNotification) o;
      return Objects.equals(this.name, emailNotification.name) &amp;&amp;
          Objects.equals(this.emailAddress, emailNotification.emailAddress) &amp;&amp;
          super.equals(o);
    }
  
    @Override
    public int hashCode() {
      return Objects.hash(name, emailAddress, super.hashCode());
    }
  
  }
  </code></pre>
  
  <p>Which is nice. But now the problem occurs during the deserialization of the JSON. When an ObjectMapper is passed the JSON corresponding to a <code>User</code> class, which has one property of type <code>Notification</code>, and the JSON is actually of type <code>EmailNotification</code>, then for some reason the deserializer doesn't care and deserializes it into a <code>Notification</code>, thus ignoring the <code>emailAddress</code> property. </p>
  
  <p>Corresponding test class:</p>
  
  <pre><code>package nl.test;
  
  import com.fasterxml.jackson.annotation.JsonInclude;
  import com.fasterxml.jackson.databind.DeserializationFeature;
  import com.fasterxml.jackson.databind.ObjectMapper;
  import org.junit.Test;
  import org.junit.runner.RunWith;
  import org.mockito.junit.MockitoJUnitRunner;
  import org.threeten.bp.LocalDate;
  
  import static com.fasterxml.jackson.databind.MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS;
  import static org.junit.Assert.*;
  
  
  @RunWith(MockitoJUnitRunner.class)
  public class ObjectMappersConfigurationTest {
  
      @Test
      public void test() throws Exception {
          String json = "{\n" +
                  "  \"user\": {\n" +
                  "    \"notification\": {\n" +
                  "      \"name\": \"somename\",\n" +
                  "      \"emailAddress\": \"test@stackoverflow.com\",\n" +
                  "      \"typeOfNotification\": \"EMAIL\"\n" +
                  "    },\n" +
                  "  }\n" +
                  "}\n";
  
          ObjectMapper mapper = createJsonObjectMapper();
          User order = mapper.readValue(json, User.class);
  
          assertEquals(1, 1);
      }
  
      public ObjectMapper createJsonObjectMapper() {
          ObjectMapper objectMapper = new ObjectMapper();
          setDefaultRelaxObjectMappings(objectMapper);
          return objectMapper;
      }
  
      public static void setDefaultRelaxObjectMappings(ObjectMapper objectMapper) {
          objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
          objectMapper.configure(DeserializationFeature.FAIL_ON_INVALID_SUBTYPE, false);
  
          objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
          objectMapper.enable(ACCEPT_CASE_INSENSITIVE_ENUMS);
      }
  }
  </code></pre>
  
  <p>And the output will be:</p>
  
  <pre><code>User {
    notification {
       notificationType: EMAIL
    }
  }
  </code></pre>
  
  <p>Where I expected:</p>
  
  <pre><code>User {
    notification {
       notificationType: EMAIL,
       emailAddress: "...",
       name: "..."
    }
  }
  </code></pre>
  
  <p>Now I know that I can use a custom deserializer for this purpose, but this seems like overkill, deserializing objects with inheritance should be a simple setting I suppose. I just can't seem to find it. </p>
  
  <p>Enabling default typing would be an alternative but I'd rather refrain from that since our YAML files come from an external party, forcing them to default type their YAML isn't the best solution IMO. </p>