OpenAPITools / OpenAPITools/openapi-generator

[BUG][Java] oneOf with enum discriminator fails to compile

Open
#9,048 5 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Issue: Bug
Dominant language
Java
Stars
26.8k
Forks
7.7k
PR merge metrics
PR metrics pending

Description

Description

When using the oneOf expression with enums the code fails to compile because the interface has a function of type "public String getType();", while the children nodes have the implemented method defined as "public TypeEnum getType() {}" which doesn't match the contract. If I manually change the concrete classes to match the interface (ex changing the TypeEnum method to public String getType() {
return type.value;
} it compiles and works fine.

I'm wondering if I'm doing something wrong or what.

Example Components

TargetingExpression:
      oneOf:
        - $ref: "#/components/schemas/TargetingPredicate"
        - $ref: "#/components/schemas/TargetingPredicateNested"
      discriminator:
        propertyName: "type"
        mapping:
          "views": "#/components/schemas/SDTargetingPredicateNested"
          "asinSameAs": "#/components/schemas/TargetingPredicate"

TargetingPredicate:
      type: "object"
      required: ["type", "value"]
      properties:
        type:
          type: "string"
          enum:
            - asinSameAs
        value:
          type: "string"

TargetingPredicateNested:
      type: "object"
      required: ["type", "value"]
      properties:
        type:
          type: "string"
          enum:
            - views
        value:
          type: "array"

Which then generates this

@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2021-03-22T22:35:47.230-04:00[America/Toronto]")
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "type", visible = true)
@JsonSubTypes({
  @JsonSubTypes.Type(value = TargetingPredicate.class, name = "asinSameAs"),
  @JsonSubTypes.Type(value = TargetingPredicateNested.class, name = "views"),
})

public interface TargetExpression  {
    public String getType();
}

//==============
@JsonPropertyOrder({
  SDTargetingPredicateV31.JSON_PROPERTY_TYPE,
  SDTargetingPredicateV31.JSON_PROPERTY_VALUE
})
@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2021-03-22T22:35:47.230-04:00[America/Toronto]")
public class TargetingPredicate implements SDTargetExpression {
  /**
   * Gets or Sets type
   */
  public enum TypeEnum {
    ASINSAMEAS("asinSameAs");

    private String value;

    TypeEnum(String value) {
      this.value = value;
    }

    @JsonValue
    public String getValue() {
      return value;
    }

    @Override
    public String toString() {
      return String.valueOf(value);
    }

    @JsonCreator
    public static TypeEnum fromValue(String value) {
      for (TypeEnum b : TypeEnum.values()) {
        if (b.value.equals(value)) {
          return b;
        }
      }
      throw new IllegalArgumentException("Unexpected value '" + value + "'");
    }
  }

  public static final String JSON_PROPERTY_TYPE = "type";
  private TypeEnum type;

  public static final String JSON_PROPERTY_VALUE = "value";
  private String value;


  public TargetingPredicate type(TypeEnum type) {
    
    this.type = type;
    return this;
  }

   /**
   * Get type
   * @return type
  **/
  @NotNull
  @ApiModelProperty(required = true, value = "")
  @JsonProperty(JSON_PROPERTY_TYPE)
  @JsonInclude(value = JsonInclude.Include.ALWAYS)

  public TypeEnum getType() {
    return type;
  }


  public void setType(TypeEnum type) {
    this.type = type;
  }


  public TargetingPredicate value(String value) {
    
    this.value = value;
    return this;
  }

   /**
   * The value to be targeted.
   * @return value
  **/
  @NotNull
  @ApiModelProperty(example = "B0123456789", required = true, value = "The value to be targeted.")
  @JsonProperty(JSON_PROPERTY_VALUE)
  @JsonInclude(value = JsonInclude.Include.ALWAYS)

  public String getValue() {
    return value;
  }


  public void setValue(String value) {
    this.value = value;
  }


  @Override
  public boolean equals(java.lang.Object o) {
    if (this == o) {
      return true;
    }
    if (o == null || getClass() != o.getClass()) {
      return false;
    }
    TargetingPredicate TargetingPredicate = (SDTargetingPredicateV31) o;
    return Objects.equals(this.type, TargetingPredicate.type) &&
        Objects.equals(this.value, TargetingPredicate.value);
  }

  @Override
  public int hashCode() {
    return Objects.hash(type, value);
  }


  @Override
  public String toString() {
    StringBuilder sb = new StringBuilder();
    sb.append("class SDTargetingPredicateV31 {\n");
    sb.append("    type: ").append(toIndentedString(type)).append("\n");
    sb.append("    value: ").append(toIndentedString(value)).append("\n");
    sb.append("}");
    return sb.toString();
  }

  /**
   * Convert the given object to string with each line indented by 4 spaces
   * (except the first line).
   */
  private String toIndentedString(java.lang.Object o) {
    if (o == null) {
      return "null";
    }
    return o.toString().replace("\n", "\n    ");
  }

}

Configuration

{
  "useBeanValidation": "true",
  "serializationLibrary": "jackson",
  "library": "jersey2",
  "java8": "true",
  "dateLibrary": "java8",
  "sourceFolder": "",
  "modelPackage": "com.models,
  "legacyDiscriminatorBehavior": false
}

openapi-generator version

Openapi-generator-4.3.1

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the supplied OpenAPI oneOf and enum discriminator schema with OpenAPI Generator 4.3.1, then inspect the generated Java interface and concrete model classes. Confirm how the discriminator getter contract is generated and verify that the resulting Java project compiles without manually editing the generated classes.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, openapi
Domain
api, tooling
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.