OpenAPITools / OpenAPITools/openapi-generator
[BUG][JAVA] Problem with request serialization / deserialization in case of oneOf caused by PR #20939
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 26.8k
- Forks
- 7.7k
- PR merge metrics
- PR metrics pending
Description
This problem is related to change in https://github.com/OpenAPITools/openapi-generator/pull/20939 related to bug report https://github.com/OpenAPITools/openapi-generator/issues/20938.
So it worked in version 7.14 and it is not working since actual 7.19.
I agree that correct behavior should be that only mapped discriminator should be included in generated interface for parent type, but it now breaks serialization / deserialization in client vs server communication.
Since parent interface contains these annotations it will override property of discriminator via Jackson mapper to simple class name but server now expect to receive explicit mapping that we have in yaml definition.
I will borrow example from original bug report with slight alternation:
FruitRequest:
discriminator:
mapping:
APPLE: '#/components/schemas/AppleRequest'
BANANA: '#/components/schemas/BananaRequest'
propertyName: fruitType
oneOf:
- $ref: '#/components/schemas/AppleRequest'
- $ref: '#/components/schemas/BananaRequest'
properties:
fruitType:
$ref: '#/components/schemas/FruitType'
required:
- fruitType
type: object
x-one-of-name: Fruit
AppleRequest:
properties:
seeds:
type: integer
required:
- seeds
type: object
BananaRequest:
properties:
length:
type: integer
required:
- length
type: object
then we will have:
@JsonIgnoreProperties(
value = {"fruitType"},
allowSetters = true
)
@JsonTypeInfo(
use = Id.NAME,
include = As.PROPERTY,
property = "fruitType",
visible = true
)
@JsonSubTypes({
@JsonSubTypes.Type(value = Apple.class, name = "APPLE"),
@JsonSubTypes.Type(value = Banana.class, name = "BANANA"),
@JsonSubTypes.Type(value = Apple.class, name = "AppleRequest"), // <-- not any more
@JsonSubTypes.Type(value = Banana.class, name = "BananaRequest") // <-- not any more
})
@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", comments = "Generator version: 7.13.0-SNAPSHOT")
public interface Fruit {
Since fruitType is marked as ignored it will not be passed from client's DTO to the request and simpleClassName will be used which will not match on server side.
If we remove that JsonIgnoreProperties then both, the explicit discriminator property value and simpleClassName will be sent to server as fruitType and again, fail on deserialization.
Only think that worked for me was to also specify
@JsonTypeInfo(
use = Id.NAME,
include = As.EXISTING_PROPERTY,
property = "fruitType",
visible = true
)
that results in:
// no more @JsonIgnoreProperties
@JsonTypeInfo(
use = Id.NAME,
include = As.EXISTING_PROPERTY,
property = "fruitType",
visible = true
)
@JsonSubTypes({
@JsonSubTypes.Type(value = Apple.class, name = "APPLE"),
@JsonSubTypes.Type(value = Banana.class, name = "BANANA"),
})
@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", comments = "Generator version: 7.13.0-SNAPSHOT")
public interface Fruit {
then its working correctly with only explicit discriminator mapping in parent interface.
There is also workaround for this issue, to define inside openapi.yml also mapping for simpleClassName
e.g.
FruitRequest:
discriminator:
mapping:
APPLE: '#/components/schemas/AppleRequest'
BANANA: '#/components/schemas/BananaRequest'
AppleRequest: '#/components/schemas/AppleRequest'
BananaRequest: '#/components/schemas/BananaRequest'
I don't kwow if possible change in https://github.com/OpenAPITools/openapi-generator/blob/master/modules/openapi-generator/src/main/resources/JavaSpring/typeInfoAnnotation.mustache would break anything else, but at least some options to enable old behavior would be greatly appreciated :-)
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 modules/openapi-generator/src/main/resources/JavaSpring/typeInfoAnnotation.mustache, then read PR #20939 and issue #20938 for the behavior change. Reproduce the FruitRequest oneOf case with the shown discriminator mapping and inspect generated Jackson annotations. Done means Java client/server serialization and deserialization preserve the explicit discriminator values without requiring duplicate simple-class-name mappings.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java, openapi
- Domain
- api, backend, tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100