swagger-core
swagger-core copied to clipboard
@ArraySchema is ignored in model property (array of abstract class)
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 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
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?