Skip to content

[BUG][jaxrs-spec] Discriminated model serializes a duplicate type with the class name instead of the discriminator value #24175

Description

@jaydeep-punjani

Bug Report Checklist

  • Have you provided a full/minimal spec to reproduce the issue?
  • Have you validated the input using an OpenAPI validator (example)?
  • Have you tested with the latest master to confirm the issue still exists?

Description

For a discriminated polymorphic model (oneOf-by-inheritance via allOf + discriminator.mapping), the jaxrs-spec generator produces Java that serializes a duplicate discriminator property with the wrong value.

The generated base class is annotated:

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type", visible = true)

and each concrete subtype gets:

@JsonTypeName("TrackMessage")   // <-- the CLASS NAME, not the discriminator value "track"

Because visible = true keeps type as a real bean property and the type id is emitted from @JsonTypeName (the class name), serializing a subtype yields a duplicate key:

{"type":"TrackMessage","type":"track", ...}

Deserialization is correct (it uses the @JsonSubTypes name = "track" mapping); only serialization is broken.

This is not fixable from the spec: x-discriminator-value (at the child schema top level or inside the allOf member), removing the type property, and removing the discriminator mapping all fail to change @JsonTypeName/visible. Removing the mapping additionally breaks reads (@JsonSubTypes then uses the class name).

openapi-generator version

Reproduced on 7.7.0, 7.11.0, and 7.14.0 (identical output).

OpenAPI declaration file content or url

openapi: 3.1.0
info: { title: repro, version: 1.0.0 }
paths: {}
components:
  schemas:
    MessageType:
      type: string
      enum: [track, page]
    AnyMessage:
      type: object
      required: [type]
      properties:
        type: { $ref: '#/components/schemas/MessageType' }
        messageId: { type: string }
      discriminator:
        propertyName: type
        mapping:
          track: '#/components/schemas/TrackMessage'
          page: '#/components/schemas/PageMessage'
    TrackMessage:
      allOf:
        - $ref: '#/components/schemas/AnyMessage'
        - type: object
          required: [event]
          properties:
            event: { type: string }
    PageMessage:
      allOf:
        - $ref: '#/components/schemas/AnyMessage'
        - type: object
          properties:
            name: { type: string }

Generation command

openapi-generator-cli generate -g jaxrs-spec -i repro.yaml -o out \
  -p interfaceOnly=true,useJakartaEe=true,useBeanValidation=true,dateLibrary=java8

Steps to reproduce

  1. Generate with the command above.
  2. Inspect AnyMessage.java@JsonTypeInfo(..., property = "type", visible = true).
  3. Inspect TrackMessage.java@JsonTypeName("TrackMessage") (class name, not track).
  4. new ObjectMapper().writeValueAsString(trackMessage){"type":"TrackMessage","type":"track", ...}.

Expected

Serializing a TrackMessage should emit a single, correct discriminator: {"type":"track", ...}. @JsonTypeName should be the discriminator value from the mapping (track), and the generator should not emit type twice (either visible = false, or suppress the redundant bean property on write).

Related issues/PRs

Searched open issues; none found matching this jaxrs-spec discriminator-serialization case.

Suggested fix

Either set @JsonTypeName to the discriminator value derived from discriminator.mapping (currently the schema/class name), or avoid double-emitting the discriminator when visible = true and a same-named bean property exists.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions