OpenAPITools / OpenAPITools/openapi-generator
[BUG][JAVA] OneOf and inline creates a selfreference in case of naming matching
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 26.8k
- Forks
- 7.7k
- PR merge metrics
- PR metrics pending
Description
Bug Report Checklist
- Have you provided a full/minimal spec to reproduce the issue?
- Have you validated the input using an OpenAPI validator (example)?
- Have you tested with the latest master to confirm the issue still exists?
- Have you searched for related issues/PRs?
- What's the actual output vs expected output?
- [Optional] Sponsorship to speed up the bug fix or feature request (example)
Description
If I have a a component that references another component in a oneOf the naming of the classes becomes the same and it creates an object with a reference to itself, with other words when generating the classes one of them gets replaced by the other one.
We are not the owners of the schema and can modify it locally, but it is a big file and a lot to modify everytime we get a new version of the definition.
For now we are using manually adding modelNameMapping to handle this, but would prefer if the naming would make sure it does not replace another already defined class.
Expected is that 2 classes that get generated, one for the oneof and one for the actual component.
Actual is that only the oneof is generated.
openapi-generator version
7.9.0
OpenAPI declaration file content or url
A simplified json verified in https://editor.swagger.io/ from the 12k line json we use:
{
"openapi": "3.0.0",
"info": {
"title": "API title",
"version": "1.0.0"
},
"paths": {
"/api/test": {
"get": {
"operationId": "Test",
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Margin"
}
}
}
}
}
}
}
}
},
"components": {
"schemas": {
"Margin": {
"type": "object",
"additionalProperties": false,
"properties": {
"price": {
"nullable": true,
"oneOf": [
{
"$ref": "#/components/schemas/MarginPrice"
}
]
},
"percent": {
"nullable": true,
"oneOf": [
{
"$ref": "#/components/schemas/Percent"
}
]
}
}
},
"MarginPrice": {
"type": "object",
"additionalProperties": false,
"properties": {
"value": {
"type": "number",
"format": "decimal",
"nullable": true
},
"currency": {
"nullable": true,
"oneOf": [
{
"$ref": "#/components/schemas/Currency"
}
]
}
}
},
"Percent": {
"type": "object",
"additionalProperties": false,
"properties": {
"value": {
"type": "number",
"format": "decimal",
"nullable": true
}
}
},
"Currency": {
"type": "object",
"description": "Currency identifier.",
"additionalProperties": false,
"required": [
"code"
],
"properties": {
"code": {
"type": "string",
"description": "Three-letter code identifying the currency according to ISO 4217, e.g. \"SEK\", \"EUR\".",
"maxLength": 3,
"minLength": 3,
"pattern": "AUD|CAD|CHF|CNY|CZK|DKK|EUR|GBP|HKD|HUF|IDR|ILS|ISK|JPY|KWD|MAD|MXN|MYR|NOK|NZD|PLN|RUB|SAR|SEK|SGD|THB|TRY|USD|ZAR",
"nullable": false
}
}
}
}
}
}
Related issues/PRs
https://github.com/OpenAPITools/openapi-generator/issues/18039
Suggest a fix
In org.openapitools.codegen.InlineModelResolver.gatherInlineModels it has a code that looks like the following:
String schemaName = resolveModelName(prop.getTitle(), modelPrefix + "_" + propName);
Resulting in a schemaName that is parentName_propName.
In org.openapitools.codegen.AbstractJavaCodegen.toModelName it has the following code:
// phone_number => PhoneNumber
final String camelizedName = camelize(nameWithPrefixSuffix);
that is used to define the classname for the class. Resulting in a classname of parentNamePropName
With this example above we would get two schemas MarginPrice and Margin_price. When converting them to classes both will be named MarginPrice and it results in the oneOf-class being the winner and the original MarginPrice gets replaced.
The suggested fix would be to have similar to what uniqueName does for InlineModelResolver, but on classname level.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with org.openapitools.codegen.InlineModelResolver.gatherInlineModels and the schemaName construction described in the issue, then trace how org.openapitools.codegen.AbstractJavaCodegen.toModelName camelizes both names. Reproduce the supplied OpenAPI schema with the Java generator and verify that both the oneOf model and the referenced MarginPrice model are generated without one replacing the other.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- backend-api-design, devtools
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 38/100