OpenAPITools / OpenAPITools/openapi-generator

[BUG][SPRING] Incorrect @JsonTypeName generated for oneOf discriminator mapping regression in 7.23.0

Open
#24,198 6 comments 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

After upgrading from OpenAPI Generator 7.12.0 to 7.23.0, the generated Spring models produce inconsistent Jackson polymorphic annotations.

The generated base interface correctly uses the discriminator mapping value:

@JsonSubTypes({
    @JsonSubTypes.Type(
        value = PickupDeliveryRequest.class,
        name = "pickupDelivery"
    )
})

However, the generated subtype is annotated with:

@JsonTypeName("PickupDeliveryRequest")

instead of

@JsonTypeName("pickupDelivery")

Because Jackson serializes using @JsonTypeName, the generated model serializes to:

{
  "requestType": "PickupDeliveryRequest",
  "pickupLocation": "STORE001"
}

instead of the discriminator mapping value:

{

  "requestType": "pickupDelivery",
  "pickupLocation": "STORE001"
}

As a result, the generated models cannot be deserialized correctly by the generated API and Spring returns HttpMessageNotReadableException (400 Bad Request).

Changing the generated annotation manually to

@JsonTypeName("pickupDelivery")

fixes the problem immediately.

This worked correctly with OpenAPI Generator 7.12.0.

openapi-generator version
Working: 7.12.0

Broken: 7.23.0
OpenAPI declaration

openapi: 3.0.3

info:
  title: Discriminator Regression
  version: 1.0.0

paths:
  /delivery:
    put:
      operationId: setDelivery
      requestBody:
        required: true
        content:
          application/json:
            schema:
              oneOf:
                - $ref: '#/components/schemas/PickupDeliveryRequest'
              discriminator:
                propertyName: requestType
                mapping:
                  pickupDelivery: '#/components/schemas/PickupDeliveryRequest'
      responses:
        "204":
          description: OK

components:
  schemas:

    SetDeliveryModeRequest:
      type: object
      required:
        - requestType
      properties:
        requestType:
          type: string

    PickupDeliveryRequest:
      allOf:
        - $ref: '#/components/schemas/SetDeliveryModeRequest'
        - type: object
          required:
            - pickupLocation
          properties:
            pickupLocation:
              type: string

Generation Details

Generator:

spring

Generator options:

documentationProvider=springdoc
useSpringBoot4=true
useJackson3=true

Steps to reproduce
Generate the Spring models.
Inspect the generated classes.

Generated base interface:

@JsonSubTypes({
    @JsonSubTypes.Type(
        value = PickupDeliveryRequest.class,
        name = "pickupDelivery"
    )
})

Generated subtype:

@JsonTypeName("PickupDeliveryRequest")
Serialize
new PickupDeliveryRequest("pickupDelivery", "STORE001")

Actual JSON:

{
  "requestType": "PickupDeliveryRequest",
  "pickupLocation": "STORE001"
}

Expected JSON:

{
  "requestType": "pickupDelivery",
  "pickupLocation": "STORE001"
}

Changing

@JsonTypeName("PickupDeliveryRequest")

to

@JsonTypeName("pickupDelivery")

causes serialization to work correctly.

Related issues/PRs

I searched for discriminator-related issues but could not find one describing this specific regression where the generated @JsonSubTypes.Type(name=...) and @JsonTypeName(...) disagree.

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

Start with the spring generator using the OpenAPI declaration and options in the issue, then inspect the generated base interface and PickupDeliveryRequest model. Compare the @JsonSubTypes.Type name with @JsonTypeName and reproduce serialization. Done means the subtype annotation uses the discriminator mapping value and generated models serialize and deserialize with requestType set to pickupDelivery.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, openapi, spring, spring-boot
Domain
api, backend, tooling
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.