Bug Report Checklist
Description
Using 7.0.0-beta of the openapi-generator-maven-plugin (library = spring-boot):
Enum Type as discriminator feature #13846 (oneOf interface polymorphism) ignores modelNameSuffix specified in the plugin configurations when generating the abstract get{Discriminator}() method for the interface, but is considering it while generating the enum and concrete class' relevant discriminator field and set/get methods. This results in a compile time error (incompatible types).
Presume this is an issue for modelNamePrefix as well.
openapi-generator version
7.0.0-beta
OpenAPI declaration file content or url
Yaml:
FruitType:
enum:
- APPLE
- BANANA
type: string
Fruit:
discriminator:
mapping:
APPLE: '#/components/schemas/Apple'
BANANA: '#/components/schemas/Banana'
propertyName: fruitType
oneOf:
- $ref: '#/components/schemas/Apple'
- $ref: '#/components/schemas/Banana'
properties:
fruitType:
$ref: '#/components/schemas/FruitType'
required:
- fruitType
type: object
Apple:
properties:
seeds:
type: integer
required:
- seeds
type: object
Banana:
properties:
length:
type: integer
required:
- length
type: object
Generation Details
Maven plugin (the bits that matter):
<configuration>
<generatorName>spring</generatorName>
<library>spring-boot</library>
<modelNameSuffix>Dto</modelNameSuffix>
....
</configuration>
Generated Discriminator Enum, Interface and Concrete classes
Enum:
@Generated(value = "org.openapitools.codegen.languages.SpringCodegen")
public enum FruitTypeDto {
APPLE("APPLE"),
BANANA("BANANA");
private String value;
FruitTypeDto(String value) {
this.value = value;
}
@JsonValue
public String getValue() {
return value;
}
@Override
public String toString() {
return String.valueOf(value);
}
@JsonCreator
public static FruitTypeDto fromValue(String value) {
for (FruitTypeDto b : FruitTypeDto.values()) {
if (b.value.equals(value)) {
return b;
}
}
throw new IllegalArgumentException("Unexpected value '" + value + "'");
}
}
Interface:
@JsonIgnoreProperties(
value = "fruitType", // ignore manually set fruitType, it will be automatically generated by Jackson during serialization
allowSetters = true // allows the fruitType to be set during deserialization
)
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "fruitType", visible = true)
@JsonSubTypes({
@JsonSubTypes.Type(value = Apple.class, name = "APPLE"),
@JsonSubTypes.Type(value = Apple.class, name = "Apple"),
@JsonSubTypes.Type(value = Banana.class, name = "BANANA"),
@JsonSubTypes.Type(value = Banana.class, name = "Banana")
})
@Generated(value = "org.openapitools.codegen.languages.SpringCodegen")
public interface Fruit {
public FruitType getFruitType();
}
Concrete class (Banana is generated the same considering the model suffix)
@Generated(value = "org.openapitools.codegen.languages.SpringCodegen")
public class Apple implements Fruit {
private Integer seeds;
private FruitTypeDto fruitType;
public Apple() {
super();
}
/**
* Constructor with only required parameters
*/
public Apple(Integer seeds) {
this.seeds = seeds;
this.fruitType = fruitType;
}
public Apple seeds(Integer seeds) {
this.seeds = seeds;
return this;
}
/**
* Get seeds
* @return seeds
*/
@NotNull
@Schema(name = "seeds", requiredMode = Schema.RequiredMode.REQUIRED)
@JsonProperty("seeds")
public Integer getSeeds() {
return seeds;
}
public void setSeeds(Integer seeds) {
this.seeds = seeds;
}
public Apple fruitType(FruitTypeDto fruitType) {
this.fruitType = fruitType;
return this;
}
/**
* Get fruitType
* @return fruitType
*/
@NotNull @Valid
@Schema(name = "fruitType", requiredMode = Schema.RequiredMode.REQUIRED)
@JsonProperty("fruitType")
public FruitTypeDto getFruitType() {
return fruitType;
}
public void setFruitType(FruitTypeDto fruitType) {
this.fruitType = fruitType;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Apple apple = (Apple) o;
return Objects.equals(this.seeds, apple.seeds) &&
Objects.equals(this.fruitType, apple.fruitType);
}
@Override
public int hashCode() {
return Objects.hash(seeds, fruitType);
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("class Apple {\n");
sb.append(" seeds: ").append(toIndentedString(seeds)).append("\n");
sb.append(" fruitType: ").append(toIndentedString(fruitType)).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(Object o) {
if (o == null) {
return "null";
}
return o.toString().replace("\n", "\n ");
}
}
Steps to reproduce
Related issues/PRs
#13846
Suggest a fix/workaround
current workarounds:
- if one wants to leverage oneOf which generates Interface and concrete classes: don't configure modelNameSuffix/modelNamePrefix
- if one wants to keep the modelNameSuffix/Prefix: Leverage composition instead--> Generate base concrete class and subclasses by removing oneOf and specify allOf in the child schemas. The resulting generated code retains the DTO in the base concrete model class.
sample yaml for option two workaround
FruitType:
enum:
- APPLE
- BANANA
type: string
Fruit:
discriminator:
mapping:
APPLE: '#/components/schemas/Apple'
BANANA: '#/components/schemas/Banana'
propertyName: fruitType
properties:
fruitType:
$ref: '#/components/schemas/FruitType'
required:
- fruitType
type: object
Apple:
allOf:
- $ref: '#/components/schemas/Fruit'
- properties:
seeds:
type: integer
required:
- seeds
type: object
Banana:
allOf:
- $ref: '#/components/schemas/Fruit'
- properties:
length:
type: integer
required:
- length
type: object
Bug Report Checklist
Description
Using 7.0.0-beta of the openapi-generator-maven-plugin (library = spring-boot):
Enum Type as discriminator feature #13846 (oneOf interface polymorphism) ignores modelNameSuffix specified in the plugin configurations when generating the abstract get{Discriminator}() method for the interface, but is considering it while generating the enum and concrete class' relevant discriminator field and set/get methods. This results in a compile time error (incompatible types).
Presume this is an issue for modelNamePrefix as well.
openapi-generator version
7.0.0-beta
OpenAPI declaration file content or url
Yaml:
Generation Details
Maven plugin (the bits that matter):
Generated Discriminator Enum, Interface and Concrete classes
Enum:
Interface:
Concrete class (Banana is generated the same considering the model suffix)
Steps to reproduce
Related issues/PRs
#13846
Suggest a fix/workaround
current workarounds:
sample yaml for option two workaround