openapi-generator: [BUG] [JavaSpring] Discriminator property gets serialized twice
openapi-generator version
3.3.4
Command line used for generation
I’m working with a JHipster API-First project, which uses openapi-generator-maven-plugin (v3.3.4).
Description
By following the OpenAPI 3.x documentation/examples, it seems that the property used as discriminator must also be specified in the properties list of the schema.
Example:
TicketEvent:
type: object
description: A generic event
discriminator:
propertyName: type
required:
- id
- sequenceNumber
- timestamp
- type
properties:
id:
type: integer
format: int64
readOnly: true
sequenceNumber:
type: integer
readOnly: true
timestamp:
type: string
format: date-time
readOnly: true
type:
type: string
readOnly: true
TicketMovedEvent:
description: A ticket move event
allOf:
- $ref: '#/components/schemas/Event'
- type: object
required:
- source
- target
properties:
source:
$ref: '#/components/schemas/Queue'
target:
$ref: '#/components/schemas/Queue'
The generated Java class for the code above seems to differ from the Jackson guidelines for polymorphic type handling with annotations, where the property used as discriminator must not be present in the class. The generated code also includes this property as a class attribute with getter/setter.
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type", visible = true)
@JsonSubTypes({
@JsonSubTypes.Type(value = TicketMovedEvent.class, name = "TicketMovedEvent")
})
public class TicketEvent {
...
@JsonProperty("type")
private String type;
This causes the serialization output to include the property twice, as shown below.
{
...
"type": "TicketMovedEvent",
"type": null,
...
}
I’ve also tried to remove the property from the OpenAPI properties list, leaving intact the discriminator part; this way the generated code corresponds to the Jackson’s guidelines and the serialization works just fine. On the other hand, I get the following error during the deserialization process.
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "type" (class it.blutec.bludesk.web.api.model.TicketMovedEvent), not marked as ignorable ...
To fix this, i’ve configured the Jackson ObjectMapper object for ignoring this kind of situations.
ObjectMapper om = new ObjectMapper()
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
By the way, this looks like a workaround to me beacuse my OpenAPI file doesn’t (strictly) follows the spec.
Suggest a fix
The generator should not include an additional attribute (with getter/setter) for a discriminator property.
About this issue
- Original URL
- State: open
- Created 5 years ago
- Reactions: 10
- Comments: 31 (8 by maintainers)
Commits related to this issue
- Add nonDiscriminatorVars to CodegenModel and use it instead of vars for JavaSpring. Fixes #3796 — committed to keenanpepper/openapi-generator by keenanpepper 5 years ago
- Add nonDiscriminatorVars to CodegenModel and use it instead of vars for JavaSpring. Fixes #3796 — committed to keenanpepper/openapi-generator by keenanpepper 5 years ago
- Add nonDiscriminatorVars to CodegenModel and use it instead of vars for JavaSpring. Fixes #3796 — committed to keenanpepper/openapi-generator by keenanpepper 5 years ago
- Use EXISTING_PROPERTY for JavaSpring as well This fixes issue #3796 for JavaSpring. It's a very straightfoward extension of #5120 for the JavaSpring generator (that PR was just for the Java generator... — committed to keenanpepper/openapi-generator by keenanpepper 4 years ago
- Use EXISTING_PROPERTY for JavaSpring as well This fixes issue #3796 for JavaSpring. It's a very straightfoward extension of #5120 for the JavaSpring generator (that PR was just for the Java generator... — committed to keenanpepper/openapi-generator by keenanpepper 4 years ago
- Use EXISTING_PROPERTY for JavaSpring as well (#5243) This fixes issue #3796 for JavaSpring. It's a very straightfoward extension of #5120 for the JavaSpring generator (that PR was just for the Java ... — committed to OpenAPITools/openapi-generator by keenanpepper 4 years ago
- Use EXISTING_PROPERTY for JavaSpring as well (#5243) This fixes issue #3796 for JavaSpring. It's a very straightfoward extension of #5120 for the JavaSpring generator (that PR was just for the Java ... — committed to MikailBag/openapi-generator by keenanpepper 4 years ago
@bonii-xx that’s exactly what I’m doing with 4.2.2 (or 4.2.3).
Actually, omitting the discriminator property in the
propertieslist is an “hack”. The OpenAPI 3.x spec clearly states:I don’t know why they accepted the
EXISTING_PROPERTYpull request, it seems to me that this project lacks of supervision.IMHO explicitely defining the discriminator property is a must, because at a certain point in time an object must be serialized to JSON (or XML) and, without an additional property valued with the class name, the class information is lost. Thus the need for specifying in which key (property) expose this info (string).
We tried to update from 4.2.3 to 4.3.1, and I stumbled upon this issue. Our serialization is now broken, because the discriminator field is missing. Before everything worked fine.
We’re using this approach, which worked fine in 4.2.3. (no field generated in the java code)
With the PR that got released with 4.3.0 we now have to explicitly define the discriminator property? Is this intended?
Version 4.3.0 broke my clients too. The include change of
JsonTypeInfo.As.PROPERTYtoJsonTypeInfo.As.EXISTING_PROPERTYbroken them.When I instantiate a new object of a sub-type class, the discriminator doesn’t exists in this object with the new strategy.
A workaround to this is add the discriminator as property in the POJO class, but in this way the client will have to fill this property when instantiate a object. I really dislike this workaround, to me the old strategy is better, and if the change is necessary, add a option (configOption) to change the include type of serialization is more convenient and attend the two cases.
I just noticed this was for Spring - this is an issue for the jaxrs-spec generator also.
This is quite frustrating. IMO the solution needs to be to remove the discriminator property from the generated POJO altogether. The whole purpose of polymorphic types in this case is to encode the type info into the class itself. Having the discriminator property on the class just introduces the possibility that it be set such that it disagrees with the actual class of the object.
Manually removing the attribute (plus getter/setter), corresponding to the discriminator property, from the generated class does the trick. As stated above, I’ve just needed to turn off the
DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIESconfiguration on theObjectMapper.I’ve also tried to use
JsonTypeInfo.As.EXISTING_PROPERTYin the discriminator’s related annotation, but with no success.I think that the
typeproperty only makes sense in the serialized version of an object; as a matter of fact, it conveys what in OO languages is modeled as classes. So I don’t see the point in having an attribute in the class representing the class itself.@nickshoe thanks for clarifying this for me.
@amir-ba, please read this: https://github.com/OpenAPITools/openapi-generator/issues/3796#issuecomment-627874116.
TL;DR:
EXISTING_PROPERTYis intended to be used only for deserialization purposes.Just wanted to share my workaround for this (not great…but it’s working until this can be fixed properly). This is specifically for folks using Spring Boot 2, but I’m sure will help other Spring and even non-Spring Java project maintainers:
This assumes a fairly standard model inheritance e.g.:
I have the same problems as mentioned above: With version 5.0.0, the plain generated code:
Anyway, right now i generate the code, change the code as mentioned above and commit it (which i would like to avoid).
Hi
I have the same problem and it seems very important to me.
Will it be solved in version 5.0.0?
@bonii-xx the two issues are related, please read all the comments.
@bkabrda it seems like the approach does work, but the change from PROPERTY to EXISTING_PROPERTY needs to be made for other generators as well, for example JavaSpring, which we are using. I’ll created a PR for this shortly.
If removing discriminator property addresses the issue, we can certainly do that.