OpenAPITools / OpenAPITools/openapi-generator

[BUG][Java] Discriminator enum with mapping

Open
#13,682 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Issue: Bug
Dominant language
Java
Stars
26.8k
Forks
7.7k
PR merge metrics
PR metrics pending

Description

Description

When a model with a discriminator field and discriminator.mapping is defined, the generated class annotations cause an unexpected output in serialization.

openapi-generator version

6.2.0

Steps to reproduce

Given the following description:

Kitten:
  type: object
  properties:
    origin:
      enum:
        - DOMESTICATED
        - FERAL
      type: string
    ...
  required:
    - origin
  discriminator:
    propertyName: origin
    mapping:
      DOMESTICATED: '#/components/schemas/Domesticated'
      FERAL: '#/components/schemas/Feral'

the generated class contains the following annotations:

@JsonIgnoreProperties(
  value = "origin", // ignore manually set origin, it will be automatically generated by Jackson during serialization
  allowSetters = true // allows the origin to be set during deserialization
)
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "origin", visible = true)
@JsonSubTypes({
  @JsonSubTypes.Type(value = Domesticated.class, name = "DOMESTICATED"),
  @JsonSubTypes.Type(value = Domesticated.class, name = "Domesticated"),
  @JsonSubTypes.Type(value = Feral.class, name = "FERAL"),
  @JsonSubTypes.Type(value = Feral.class, name = "Feral")
})

@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2022-10-13T10:27:58.342752+02:00[Europe/Brussels]")
public class Kitten {
...

The problem with this is when it is serialized, e.g. using Jackson:

String kitten = new ObjectMapper().writeValueAsString(new Kitten().origin(OriginEnum.DOMESTICATED));
System.out.println(kitten);

the result is:

{"origin":"Kitten","id":null,"name":null,"price":null,"color":null,"pictureIds":null}

when the expected value for the origin field is "DOMESTICATED". I also made some test where the result was "Domesticated" (which is also not the desired output)

With version 5.4.0, the same definition outputs the code that generates the desired output:

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "origin", visible = true)
@JsonSubTypes({
  @JsonSubTypes.Type(value = Domesticated.class, name = "DOMESTICATED"),
  @JsonSubTypes.Type(value = Feral.class, name = "FERAL"),
})
@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2022-10-13T10:32:14.126224+02:00[Europe/Brussels]")
public class Kitten   {
...

Disclaimer: I am aware that the mapping is unnecessary here, it is just an example. Without the discriminator.mapping defined, the output is correct.

Let me know if further clarification is needed and thank you in advance for comments.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the Java Spring generation from the supplied OpenAPI discriminator.mapping example and compare its annotations with the 5.4.0 output. Trace the generator entry point or template that emits @JsonTypeInfo and @JsonSubTypes, then verify serialization with Jackson produces the enum value "DOMESTICATED" rather than a schema or class name.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
api, backend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.