-
-
Notifications
You must be signed in to change notification settings - Fork 7.4k
Description
This problem is related to change in #20939 related to bug report #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: objectthen 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 :-)