Skip to content

[Java][Spring] Use discriminator value for @JsonTypeName instead of schema name (#23997)#24003

Open
seonwooj0810 wants to merge 1 commit into
OpenAPITools:masterfrom
seonwooj0810:fix/issue-23997-java-spring-discriminator-jsontypename
Open

[Java][Spring] Use discriminator value for @JsonTypeName instead of schema name (#23997)#24003
seonwooj0810 wants to merge 1 commit into
OpenAPITools:masterfrom
seonwooj0810:fix/issue-23997-java-spring-discriminator-jsontypename

Conversation

@seonwooj0810

@seonwooj0810 seonwooj0810 commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Fixes #23997

Problem

For the java and spring generators, generated child models of a discriminator can receive a Jackson @JsonTypeName annotation using the schema/model name instead of the discriminator value declared in the OpenAPI contract:

@JsonTypeName("ComponentBrLock")               // wrong
public class ComponentBrLockConsumerDTO implements BrLockConsumerDTO { }

This breaks Jackson polymorphic serialization whenever the discriminator value differs from the schema name — most visibly when modelNameSuffix/modelNamePrefix is used, or when an explicit x-discriminator-value is declared on the child schema. The parent's @JsonSubTypes already uses the correct value, so serialization and deserialization disagree.

Fix

Render @JsonTypeName from vendorExtensions.x-discriminator-value when present, falling back to the schema/model name otherwise — exactly the approach suggested in the issue and already used for the jaxrs-spec generator (#23509):

@JsonTypeName("{{#vendorExtensions.x-discriminator-value}}{{{vendorExtensions.x-discriminator-value}}}{{/vendorExtensions.x-discriminator-value}}{{^vendorExtensions.x-discriminator-value}}{{name}}{{/vendorExtensions.x-discriminator-value}}")

Applied to the base Java/JavaSpring pojo.mustache and the affected Java client libraries (restclient, resttemplate, webclient, feign, jersey2, jersey3, microprofile) so the behavior is consistent across the Java/Spring generators.

The change is a no-op when no x-discriminator-value is present (the conditional renders exactly {{name}} as before), so no existing samples change.

Test evidence

Added two focused tests reproducing the issue's spec (child schemas extend a non-discriminator base and carry an explicit x-discriminator-value, generated with a model-name suffix):

  • SpringCodegenTest#testDiscriminatorValueUsedInJsonTypeName_issue23997
  • JavaClientCodegenTest#testDiscriminatorValueUsedInJsonTypeName_issue23997

Both assert child models emit @JsonTypeName("USER") / @JsonTypeName("COMPONENT") rather than the suffixed schema name. Both pass:

Tests run: 1, Failures: 0, Errors: 0, Skipped: 0  -- SpringCodegenTest
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0  -- JavaClientCodegenTest

Regenerating an existing discriminator-bearing sample (bin/configs/java-restclient.yaml, petstore) produced zero diff, confirming the template change does not affect output when x-discriminator-value is absent.

Verification done

cc @bbdouglas @sreeshas @jfiala @lukoyanov @cbornet @jimschubert (Java technical committee) and @cachescrubber @welshm @MelleD @atextor @manedev79 @javisst @borsch @banlangzhi @sahilgarg17 (Spring technical committee)


Summary by cubic

Use the discriminator value for Jackson @JsonTypeName in Java and Spring generators to fix mismatched polymorphic serialization when it differs from the schema name. Falls back to the model name when no x-discriminator-value is set; no behavior change otherwise. Fixes #23997.

  • Bug Fixes
    • Render @JsonTypeName from vendorExtensions.x-discriminator-value, otherwise use {{name}}.
    • Applied to Java/JavaSpring pojo.mustache and Java client libs: restclient, resttemplate, webclient, feign, jersey2, jersey3, microprofile.
    • Added focused tests asserting @JsonTypeName("USER" | "COMPONENT") is emitted; existing samples show zero diff.

Written for commit 91b6b9c. Summary will update on new commits.

Review in cubic

…chema name (OpenAPITools#23997)

For the java and spring generators, child models honor an explicit
x-discriminator-value vendor extension when rendering the Jackson
@JsonTypeName annotation, falling back to the schema/model name when no
discriminator value is available. Previously the schema/model name was
always used, which broke Jackson polymorphic serialization whenever the
discriminator value differed from the model name (e.g. when modelNameSuffix
is used or an explicit mapping is declared).

Mirrors the prior jaxrs-spec fix (OpenAPITools#23509). The template change is a no-op
when no x-discriminator-value is present, so existing samples are unchanged.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 12 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="modules/openapi-generator/src/main/resources/Java/libraries/microprofile/pojo.mustache">

<violation number="1" location="modules/openapi-generator/src/main/resources/Java/libraries/microprofile/pojo.mustache:17">
P2: `x-discriminator-value` is interpolated raw into a Java string literal via triple-brace Mustache, risking uncompilable generated code if the extension contains quotes, backslashes, or newlines.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

{{#isClassnameSanitized}}
{{^hasDiscriminatorWithNonEmptyMapping}}
@JsonTypeName("{{name}}")
@JsonTypeName("{{#vendorExtensions.x-discriminator-value}}{{{vendorExtensions.x-discriminator-value}}}{{/vendorExtensions.x-discriminator-value}}{{^vendorExtensions.x-discriminator-value}}{{name}}{{/vendorExtensions.x-discriminator-value}}")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: x-discriminator-value is interpolated raw into a Java string literal via triple-brace Mustache, risking uncompilable generated code if the extension contains quotes, backslashes, or newlines.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At modules/openapi-generator/src/main/resources/Java/libraries/microprofile/pojo.mustache, line 17:

<comment>`x-discriminator-value` is interpolated raw into a Java string literal via triple-brace Mustache, risking uncompilable generated code if the extension contains quotes, backslashes, or newlines.</comment>

<file context>
@@ -14,7 +14,7 @@
 {{#isClassnameSanitized}}
 {{^hasDiscriminatorWithNonEmptyMapping}}
-@JsonTypeName("{{name}}")
+@JsonTypeName("{{#vendorExtensions.x-discriminator-value}}{{{vendorExtensions.x-discriminator-value}}}{{/vendorExtensions.x-discriminator-value}}{{^vendorExtensions.x-discriminator-value}}{{name}}{{/vendorExtensions.x-discriminator-value}}")
 {{/hasDiscriminatorWithNonEmptyMapping}}
 {{/isClassnameSanitized}}
</file context>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] [JAVA][SPRING] @JsonTypeName ignores x-discriminator-value and discriminator mappings

1 participant