From 72f54fe87bc486f26fd7abfad49449c190655011 Mon Sep 17 00:00:00 2001 From: seonwoo_jung <79202163+seonwooj0810@users.noreply.github.com> Date: Sat, 12 Sep 2026 14:24:38 +0900 Subject: [PATCH 1/2] fix(java): don't emit unqualified enum default for discriminator ref-to-property A discriminator property that is a `$ref` to another schema's inline enum property (rather than a ref to a named enum schema, or an inline enum itself) still has its allowableValues/default resolved by updateCodegenPropertyEnum, but there is no enum type at this property's own use site to qualify the value with. toEnumDefaultValue was called regardless, falling back to the raw (non-enum) datatype, producing uninitializable code such as `this.category = String.ARCHIVE;` in the okhttp-gson library's generated subtype constructor. Only call toEnumDefaultValue when the property is actually an inline enum (var.isEnum) or resolves to a named enum schema (referencedSchema); otherwise drop the default rather than emit an unqualified token. Verified the full java-* sample set (bin/configs/java-*.yaml, 136 generators) regenerates with zero model/pojo diffs, so no existing sample exercises this edge case. Fixes #24874 --- .../openapitools/codegen/DefaultCodegen.java | 13 ++++++- .../codegen/java/JavaClientCodegenTest.java | 21 +++++++++++ .../src/test/resources/bugs/issue_24874.yaml | 35 +++++++++++++++++++ 3 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 modules/openapi-generator/src/test/resources/bugs/issue_24874.yaml diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java index ddae177f7b85..2d69c15a1bb0 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java @@ -7155,7 +7155,18 @@ public void updateCodegenPropertyEnum(CodegenProperty var) { } } if (enumName != null) { - var.defaultValue = toEnumDefaultValue(var, enumName); + if (var.isEnum || referencedSchema.isPresent()) { + var.defaultValue = toEnumDefaultValue(var, enumName); + } else { + // Neither an inline nested enum (var.isEnum) nor a ref to a named enum + // schema (referencedSchema): var.datatypeWithEnum is just the raw scalar + // type (e.g. a discriminator property that is a `$ref` into another + // schema's property rather than a ref to the enum schema itself). + // allowableValues/enum matching still ran, but there's no enum constant to + // qualify the value with. Drop the default rather than emit a bare, + // unqualified token that would not compile (see #24874). + var.defaultValue = null; + } } } } diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/JavaClientCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/JavaClientCodegenTest.java index 12cbe5bd2cd7..272e05a611dc 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/JavaClientCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/JavaClientCodegenTest.java @@ -1869,6 +1869,27 @@ public void testObjectDefaultWithEnumProperty_issue24298() { .contains("new OutputFormat().order(OutputFormat.OrderEnum.SIMILARITY).limit(10)"); } + @Test + public void testDiscriminatorPropertyRefToEnumDoesNotEmitInvalidDefault_issue24874() { + final Path output = newTempFolder(); + final CodegenConfigurator configurator = new CodegenConfigurator() + .setGeneratorName(JAVA_GENERATOR) + .setInputSpec("src/test/resources/bugs/issue_24874.yaml") + .setAdditionalProperties(Map.of(MODEL_NAME_PREFIX, "Stock")) + .setOutputDir(output.toString().replace("\\", "/")); + + Map files = new DefaultGenerator().opts(configurator.toClientOptInput()).generate().stream() + .collect(Collectors.toMap(File::getName, Function.identity())); + + // CategoryEvent.category is a discriminator property that is a `$ref` to another schema's + // (CategorySource) inline enum property, not to a named enum schema and not an inline enum + // itself. There is no enum type at this use site to qualify the discriminator mapping value + // with, so no default must be emitted here; previously this rendered the uncompilable + // `this.category = String.ARCHIVE;` (see #24874). + JavaFileAssert.assertThat(files.get("StockArchiveCategoryEvent.java")) + .fileDoesNotContain("String.ARCHIVE"); + } + @Test public void testWebClientJsonCreatorWithNullable_issue12790() { final Path output = newTempFolder(); diff --git a/modules/openapi-generator/src/test/resources/bugs/issue_24874.yaml b/modules/openapi-generator/src/test/resources/bugs/issue_24874.yaml new file mode 100644 index 000000000000..6d7267dcce6c --- /dev/null +++ b/modules/openapi-generator/src/test/resources/bugs/issue_24874.yaml @@ -0,0 +1,35 @@ +openapi: "3.1.0" +info: + title: Shared category discriminator + version: 1.0.0 +paths: {} +components: + schemas: + CategorySource: + type: object + required: + - category + properties: + category: + type: string + enum: + - ARCHIVE + CategoryEvent: + type: object + required: + - category + properties: + category: + description: Event category + $ref: "#/components/schemas/CategorySource/properties/category" + discriminator: + propertyName: category + mapping: + ARCHIVE: "#/components/schemas/ArchiveCategoryEvent" + ArchiveCategoryEvent: + allOf: + - $ref: "#/components/schemas/CategoryEvent" + - type: object + properties: + value: + type: string From 2f8a35fb4f352251ae6420bcda8cc7703d841911 Mon Sep 17 00:00:00 2001 From: seonwoo_jung <79202163+seonwooj0810@users.noreply.github.com> Date: Tue, 15 Sep 2026 23:36:49 +0900 Subject: [PATCH 2/2] fix(java): use languageSpecificPrimitives check instead of referencedSchema presence referencedSchema's name match against the raw dataType string is brittle for codegens whose dataType is namespace/package-qualified (e.g. PHP's OpenAPI\Server\Model\Foo), which never matched toModelName(...) and incorrectly dropped valid enum defaults for genuine named-enum refs (PhpSymfonyServerCodegenTest#testModelPropertyEnumRefWithDefaultUsesNativeEnumCaseInCodegen was failing CI). Switch the else-branch guard to check languageSpecificPrimitives instead, which is a more direct test for "is there no enum class at this use site to qualify the value with". Addresses CI failure reported at https://github.com/OpenAPITools/openapi-generator/pull/24934#issuecomment-5674500620 --- .../openapitools/codegen/DefaultCodegen.java | 23 ++++++++++++------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java index 2d69c15a1bb0..34ad7d0a049a 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java @@ -7155,16 +7155,23 @@ public void updateCodegenPropertyEnum(CodegenProperty var) { } } if (enumName != null) { - if (var.isEnum || referencedSchema.isPresent()) { + if (var.isEnum || !languageSpecificPrimitives.contains(varDataType)) { var.defaultValue = toEnumDefaultValue(var, enumName); } else { - // Neither an inline nested enum (var.isEnum) nor a ref to a named enum - // schema (referencedSchema): var.datatypeWithEnum is just the raw scalar - // type (e.g. a discriminator property that is a `$ref` into another - // schema's property rather than a ref to the enum schema itself). - // allowableValues/enum matching still ran, but there's no enum constant to - // qualify the value with. Drop the default rather than emit a bare, - // unqualified token that would not compile (see #24874). + // Not an inline nested enum (var.isEnum) and varDataType is a raw + // language-specific primitive (e.g. "String"): there's no enum class at + // this use site to qualify the value with (e.g. a discriminator property + // that is a `$ref` into another schema's property rather than a ref to the + // enum schema itself). allowableValues/enum matching still ran, but + // emitting a bare, unqualified token like `String.ARCHIVE` would not + // compile. Drop the default instead (see #24874). + // + // Note: this check is intentionally based on languageSpecificPrimitives + // rather than referencedSchema.isPresent() — referencedSchema's name match + // against the raw dataType string is brittle for codegens whose dataType is + // namespace/package-qualified (e.g. PHP's `OpenAPI\Server\Model\Foo`), which + // would never match `toModelName(...)` and incorrectly drop valid enum + // defaults for genuine named-enum refs. var.defaultValue = null; } }