While generating code with oneOf two models as a response (or request body) with Spring generator (openapi-generator-maven-plugin) code for the oneOf model is not generated.
For the given spec below the only generated models are Model1 and Model2 but the interface uses a model named OneOfModel1Model2 and a file named OneOfModel1Model2.java is not generated which cause a compilation error:
import api.generated.models.OneOfModel1Model2;
. . .
@Validated
@Api(value = "Default", description = "the Default API")
public interface DefaultApi {
/**
* GET /test : Your GET endpoint
*
* @return OK (status code 200)
*/
@ApiOperation(value = "Your GET endpoint", nickname = "getTest", notes = "", response = OneOfModel1Model2.class, tags={ })
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK", response = OneOfModel1Model2.class) })
@RequestMapping(value = "/test",
produces = { "application/json" },
method = RequestMethod.GET)
ResponseEntity<OneOfModel1Model2> getTest();
}
Tried with openapi-generator-maven-plugin 4.3.0 and 4.3.1.
{
"openapi": "3.0.0",
"info": {
"title": "testAPI",
"version": "1.0"
},
"servers": [
{
"url": "http://localhost:3000"
}
],
"paths": {
"/test": {
"get": {
"summary": "Your GET endpoint",
"tags": [],
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"oneOf": [
{
"$ref": "#/components/schemas/Model1"
},
{
"$ref": "#/components/schemas/Model2"
}
]
}
}
}
}
},
"operationId": "get-test"
}
}
},
"components": {
"schemas": {
"Model1": {
"title": "Model1",
"type": "object",
"properties": {
"id1": {
"type": "string"
}
}
},
"Model2": {
"title": "Model2",
"type": "object",
"properties": {
"id2": {
"type": "integer"
}
}
}
}
}
}
Plugin configuration
<properties>
<kotlin.vesion>1.3.41</kotlin.vesion>
<pact.artifactory.folder />
<!--openapi generator-->
<openapi-generator.version>4.3.1</openapi-generator.version>
<openapi-generator.resources>/src/main/resources</openapi-generator.resources>
<openapi-generator.specfile>api.json</openapi-generator.specfile>
<openapi-generator.language>spring</openapi-generator.language>
<openapi-generator.datelibrary>java8</openapi-generator.datelibrary>
<openapi-generator.basepackage>api</openapi-generator.basepackage>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<version>${openapi-generator.version}</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<inputSpec>
${project.basedir}${openapi-generator.resources}/${openapi-generator.specfile}
</inputSpec>
<output>${project.build.directory}/generated-sources</output>
<generatorName>${openapi-generator.language}</generatorName>
<skipValidateSpec>true</skipValidateSpec>
<configOptions>
<sourceFolder>.</sourceFolder>
<dateLibrary>java8</dateLibrary>
<interfaceOnly>true</interfaceOnly>
<skipDefaultInterface>true</skipDefaultInterface>
<useTags>true</useTags>
</configOptions>
<modelPackage>${openapi-generator.basepackage}.generated.models</modelPackage>
<apiPackage>${openapi-generator.basepackage}.generated.api</apiPackage>
<generateModelDocumentation>false</generateModelDocumentation>
<generateApiDocumentation>false</generateApiDocumentation>
<generateModelDocumentation>false</generateModelDocumentation>
<generateApiDocumentation>false</generateApiDocumentation>
<generateSupportingFiles>false</generateSupportingFiles>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Thanks :)
Seeing it as well
Hello.
I am also getting the same.
I can only guess that the implementation for Spring should be a Response Entity containing an "Object" type as opposed to the generated model.
I could of course for now just have it return "Object" but then the other aspects like documentation and client library generation will not be as accurate.
Thanks.


'/purchases/{purchaseID}/payment-intent':
parameters:
- schema:
type: string
format: uuid
name: purchaseID
in: path
required: true
description: The ProductPurchaseID - UUID
post:
summary: Create a Payment Intent for a Product Purchase
operationId: createPaymentIntentForPurchase
responses:
'201':
description: Created
content:
application/json:
schema:
oneOf:
- $ref: '#/components/schemas/StripePaymentIntent'
description: |-
Create a payment intent for the product purcahse for the UX to handle payment.
For example, passing the psp=STRIPE parameter will create a Stripe-Payment Intent for the product purchase.
parameters:
- schema:
type: string
enum:
- STRIPE
- PAYPAL
- SAGE
in: query
name: psp
description: The payment service provider to use.
required: true
tags:
- Web

In order to get a OneOf* class you have to make it a named component, then reference that in schema with a $ref.
This seems to be a universal case for the plugin, an "inline" definition does not result in a generated class (with some few exceptions.)
@hrkristian Can you give an example of what the named component would look like in the oneOf case?
I tried the following and as a result I got 4 classes. ObjectA, ObjectC, and ObjectD are all as defined. ObjectB is a combination of ObjectA and ObjectB, containing properties from both, but without any "oneof" type validation nor any inheritance with ObjectC and ObjectD.
"ObjectA": {
"type": "object",
"properties": {
"FancyProperty": {
"$ref": "#/components/schemas/ObjectB"
}
}
},
"ObjectB": {
"oneOf": [
{
"type": "string"
},
{
"$ref": "#/components/schemas/ObjectC"
},
{
"$ref": "#/components/schemas/ObjectD"
}
]
},
"ObjectC": {
"type": "object",
"properties": {
"title": {
"type": "string"
},
"value": {
"type": "object"
},
"message": {
"type": "string"
}
}
},
"ObjectD": {
"type": "object",
"properties": {
"something": {
"type": "string"
}
}
}
Most helpful comment
Hello.
I am also getting the same.
I can only guess that the implementation for Spring should be a Response Entity containing an "Object" type as opposed to the generated model.
I could of course for now just have it return "Object" but then the other aspects like documentation and client library generation will not be as accurate.
Thanks.
'/purchases/{purchaseID}/payment-intent': parameters: - schema: type: string format: uuid name: purchaseID in: path required: true description: The ProductPurchaseID - UUID post: summary: Create a Payment Intent for a Product Purchase operationId: createPaymentIntentForPurchase responses: '201': description: Created content: application/json: schema: oneOf: - $ref: '#/components/schemas/StripePaymentIntent' description: |- Create a payment intent for the product purcahse for the UX to handle payment. For example, passing the psp=STRIPE parameter will create a Stripe-Payment Intent for the product purchase. parameters: - schema: type: string enum: - STRIPE - PAYPAL - SAGE in: query name: psp description: The payment service provider to use. required: true tags: - Web