swagger-api / swagger-api/swagger-codegen-generators
[Java] [Jackson] discriminator is annotated with @JsonTypeId, which causes empty "type" on serialization
Nobody has claimed this yet.
- Dominant language
- Mustache
- Stars
- 299
- Forks
- 439
- PR merge metrics
- No merged PRs in 30d
Description
We generate the oas3 schema from the java classes which use polymorphism. The schema that we get looks right:
{
"openapi": "3.0.1",
"info": {
"title": "OpenAPI definition",
"version": "v0"
},
"servers": [
{
"url": "http://localhost:8080",
"description": "Generated server url"
}
],
"paths": {
"/pets/{name}": {
"get": {
"tags": [
"Pets"
],
"summary": "get a pet",
"operationId": "getPet",
"parameters": [
{
"name": "name",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "OK",
"content": {
"*/*": {
"schema": {
"$ref": "#/components/schemas/PetResponse"
}
}
}
}
}
}
}
},
"components": {
"schemas": {
"Cat": {
"type": "object",
"allOf": [
{
"$ref": "#/components/schemas/Pet"
}
]
},
"Dog": {
"type": "object",
"allOf": [
{
"$ref": "#/components/schemas/Pet"
}
]
},
"Pet": {
"required": [
"type"
],
"type": "object",
"properties": {
"name": {
"type": "string"
},
"type": {
"type": "string"
}
},
"discriminator": {
"propertyName": "type"
}
},
"PetResponse": {
"type": "object",
"properties": {
"pet": {
"oneOf": [
{
"$ref": "#/components/schemas/Cat"
},
{
"$ref": "#/components/schemas/Dog"
}
]
}
}
}
}
}
}
The relevant source Java classes look like this:
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
@JsonSubTypes({
@JsonSubTypes.Type(value = Cat.class, name = "Cat"),
@JsonSubTypes.Type(value = Dog.class, name = "Dog")
})
public abstract class Pet {
public String name;
}
public class Dog extends Pet{
}
public class Cat extends Pet{
}
What we get from the codegen (we use swagger-codegen-maven-plugin version 3.0.46) is this:
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type", visible = true )
@JsonSubTypes({
@JsonSubTypes.Type(value = Cat.class, name = "Cat"),
@JsonSubTypes.Type(value = Dog.class, name = "Dog"),
})
public class Pet {
@JsonProperty("name")
private String name = null;
@JsonTypeId
private String type = null;
...
When we serialize:
Cat cat = (Cat) new Cat().name("charly");
objectMapper.writeValueAsString(cat);
result looks like this:
{
"type" : "",
"name" : "charly"
}
For the serialization to work properly, I have to modify the generated Pet.java as follows:
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type", visible = true )
@JsonSubTypes({
@JsonSubTypes.Type(value = Cat.class, name = "Cat"),
@JsonSubTypes.Type(value = Dog.class, name = "Dog"),
})
@JsonIgnoreProperties(
value = "type", // ignore manually set type, it will be automatically generated by Jackson during serialization
allowSetters = true // allows the type to be set during deserialization
)
public class Pet {
@JsonProperty("name")
private String name = null;
private String type = null;
...
So I remove the @JsonTypeId and I add the @JsonIgnoreProperties for the type variable.
Which I think as how the code should be generated. @JsonTypeId marks a field for overriding the type id. So since type is null, we get an empty value in JSON. What should be done is that the discriminator property should be ignored, so that Jackson can populate it with the type name automatically.
Looks like the @JsonTypeId was added as result of this issue: #105 Back then it looks like Jackson was behaving differently and type was still populated. This looks however like it was an incorrect handling of @JsonTypeId on Jackson side.
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 the generator templates or entry points that produce the generated Pet.java shown in the report, using the swagger-codegen-maven-plugin output as the reproduction. Verify serialization of Cat with Jackson and update generation so the discriminator is populated correctly without producing an empty type value; confirm the generated classes serialize the expected type name.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100