swagger-core icon indicating copy to clipboard operation
swagger-core copied to clipboard

@ArraySchema is ignored in model property (array of abstract class)

Open AlexandrosG opened this issue 5 years ago • 2 comments

I have the following class that returns an array of abstract classes that looks like this:

@JsonPropertyOrder({"answers"})
@Schema(name = QuestionAnswers, description = "")
public final class QuestionAnswersJson extends AbstractJson {
  @ArraySchema(schema = @Schema(oneOf = {XAnswerJson.class, YAnswerJson.class, //
      ZAnswerJson.class, BAnswerJson.class}))
  private List<AbstractAnswerJson> answers = new ArrayList<>();
  
  public QuestionAnswersJson(@Nonnull List<AbstractAnswerJson> answers) {
    answers = Preconditions.checkNotNull(answers);
  }
  
  public QuestionAnswersJson() {
    // for JSON-to-Java conversion
  }
  
  public List<AbstractAnswerJson> getAnswers() {
    return answers;
  }
  
  public void setAnswers(List<AbstractAnswerJson> answers) {
    answers = answers;
  }  
}

The @ArraySchema annotation is completely ignored and the resulting class in the YAML file is an array of AbstractAnswers:

"QuestionAnswers" : {
        "type" : "object",
        "properties" : {
          "answers" : {
            "type" : "array",
            "items" : {
              "$ref" : "#/components/schemas/AbstractAnswer"
            }
          }
        }

But I would like to have something similar to this:

"QuestionAnswers" : {
        "type" : "object",
        "properties" : {
          "answers" : {
            "type" : "array",
            "items" : {
              oneOf:
                "$ref" : "#/components/schemas/XAnswer"
                "$ref" : "#/components/schemas/YAnswer"
                "$ref" : "#/components/schemas/ZAnswer"
                "$ref" : "#/components/schemas/BAnswer"
            }
          }
        }

Is that something incorrectly done on my side or is there a bug regarding @ArraySchema?

AlexandrosG avatar Aug 31 '20 15:08 AlexandrosG

@AlexandrosG thanks for reporting this.

Trying to reproduce this with a similar test (as classes/ and test details are missing from the one shared):

@JsonPropertyOrder({"answers"})
@Schema(name = "QuestionAnswers", description = "")
public final class QuestionAnswersJson {
    @ArraySchema(schema = @Schema(oneOf = {XAnswerJson.class, ZAnswerJson.class}))
    private List<AbstractAnswerJson> answers = new ArrayList<>();

    public QuestionAnswersJson(@NotNull List<AbstractAnswerJson> answers) {

    }

    public QuestionAnswersJson() {
        // for JSON-to-Java conversion
    }

    public List<AbstractAnswerJson> getAnswers() {
        return answers;
    }

    public void setAnswers(List<AbstractAnswerJson> answers) {
        answers = answers;
    }

    public static class AbstractAnswerJson {
    }

    public static class XAnswerJson extends AbstractAnswerJson {
        public String bar;
    }

    public static class ZAnswerJson extends AbstractAnswerJson {
        public String tar;
    }
}

The resolved YAML is:

AbstractAnswerJson:
  type: object
  oneOf:
  - $ref: '#/components/schemas/XAnswerJson'
  - $ref: '#/components/schemas/ZAnswerJson'
QuestionAnswers:
  type: object
  properties:
    answers:
      type: array
      items:
        $ref: '#/components/schemas/AbstractAnswerJson'
XAnswerJson:
  type: object
  properties:
    foo:
      type: string
    bar:
      type: string
ZAnswerJson:
  type: object
  properties:
    foo:
      type: string
    tar:
      type: string

which matches your expected outcome I believe (oneOfs are wrapped into AbstractAnswerJson which is how resolving works currently).

If this is not the case, kindly provide a complete test with actual and expected output, otherwise please close ticket

frantuma avatar Sep 21 '20 13:09 frantuma

I'm also facing this. I think that putting the oneOf into AbstractAnswerJson may not be optimal. What if I also use AbstractAnswerJson in a different part of the code, but only want to allow AAnswerJson and BAnswerJson there?

jochenberger avatar Jan 30 '25 13:01 jochenberger