Skip to content

[Java] fix invalid valueOf() usage in enum templates - #24838

Open
jorgerod wants to merge 8 commits into
OpenAPITools:masterfrom
InditexTech:issue-20188-java-fix-inner-enum-template-v3
Open

[Java] fix invalid valueOf() usage in enum templates#24838
jorgerod wants to merge 8 commits into
OpenAPITools:masterfrom
InditexTech:issue-20188-java-fix-inner-enum-template-v3

Conversation

@jorgerod

@jorgerod jorgerod commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

PR checklist

  • Read the contribution guidelines.
  • Pull Request title clearly describes the work in the pull request and Pull Request description provides details about how to validate the work. Missing information here may result in delayed response from the community.
  • Run the following to build the project and update samples:
    ./mvnw clean package || exit
    ./bin/generate-samples.sh ./bin/configs/*.yaml || exit
    ./bin/utils/export_docs_generators.sh || exit
    
    (For Windows users, please run the script in Git BASH)
    Commit all changed files.
    This is important, as CI jobs will verify all generator outputs of your HEAD commit as it would merge with master.
    These must match the expectations made by your contribution.
    You may regenerate an individual generator by passing the relevant config(s) as an argument to the script, for example ./bin/generate-samples.sh bin/configs/java*.
    IMPORTANT: Do NOT purge/delete any folders/files (e.g. tests) when regenerating the samples as manually written tests may be removed.
  • File the PR against the correct branch: master (upcoming 7.x.0 minor release - breaking changes with fallbacks), 8.0.x (breaking changes without fallbacks)
  • If your PR is targeting a particular programming language, @mention the technical committee members, so they are more likely to review the pull request.

Technical Committee

@bbdouglas (2017/07) @sreeshas (2017/08) @jfiala (2017/08) @lukoyanov (2017/09) @cbornet (2017/09) @jeff9finger (2018/01) @karismann (2019/03) @Zomzog (2019/04) @lwlee2608 (2019/10) @martin-mfg (2023/08)

Description

This supersedes #21055, which had become unmergeable (conflicting with master) and whose author is no longer available. As requested by @wing328 (comment), this is a fresh PR based on the current master, with all conflicts resolved and the CI failures fixed. Full credit to @timon-sbr and @martin-mfg (kept as co-authors of the commit).

Problem

The Java enum templates wrapped every enum value with {{dataType}}.valueOf(...):

{{{name}}}({{^isUri}}{{dataType}}.valueOf({{/isUri}}{{{value}}}{{^isUri}}){{/isUri}})

valueOf() is not available for every possible data type, which produces code that does not compile:

  • BigDecimal has no BigDecimal.valueOf(BigDecimal) — e.g. type: number enums.

  • UUID has no valueOf either. AbstractJavaCodegen.toEnumValue already returns UUID.fromString("...") for UUID enums, so the templates emitted UUID.valueOf(UUID.fromString(...)). This mirrors URI, which was already excluded.

  • Object has no valueOf at all — e.g. an inline enum: without an explicit type, or a type: string enum with additionalProperties: false, which currently map to Object:

    public enum OrderStatusEnum {
      PENDING(Object.valueOf("PENDING")),   // does not compile
      PROCESSING(Object.valueOf("PROCESSING"));

Fix

valueOf() is now only emitted for types that actually provide it, i.e. it is skipped for isUri, isUuid, isNumeric and isFreeFormObject:

{{{name}}}({{^isUri}}{{^isUuid}}{{^isNumeric}}{{^isFreeFormObject}}{{dataType}}.valueOf({{/isFreeFormObject}}{{/isNumeric}}{{/isUuid}}{{/isUri}}{{{value}}}{{^isUri}}{{^isUuid}}{{^isNumeric}}{{^isFreeFormObject}}){{/isFreeFormObject}}{{/isNumeric}}{{/isUuid}}{{/isUri}})

The wrapper was originally added to fix Boolean enums (#19815), and Boolean/String/Integer keep using valueOf(), so this is non-breaking.

Templates updated:

  • Java/modelInnerEnum.mustache
  • Java/libraries/microprofile/enumClass.mustache (both the withXml and non-withXml branches)
  • JavaJaxRS/spec/enumClass.mustache
  • JavaJaxRS/cxf/enumClass.mustache
  • JavaJaxRS/cxf-cdi/enumClass.mustache
  • JavaJaxRS/cxf-ext/enumClass.mustache
  • java-helidon/client/libraries/mp/enumClass.mustache
  • java-helidon/client/libraries/se/enumClass.mustache
  • java-helidon/server/libraries/mp/enumClass.mustache

Differences vs. #21055

  • Rebuilt on current master, so no merge conflicts.
  • Java/libraries/okhttp-gson/modelInnerEnum.mustache no longer needs a change: master already emits {{{name}}}({{{value}}}) there.
  • Fixed the unbalanced parentheses in Java/libraries/microprofile/enumClass.mustache that were introduced in [JAVA][BUG] Do not use valueOf for numeric types for generating inner enums Current Master #21055 (the closing ) was split into two separate mustache sections, producing String.valueOf("A")))). This was the cause of the CI failure reported in that PR.
  • Extended the fix to the JavaJaxRS/* templates, which were still emitting the invalid Object.valueOf(...) for the newly added test case. There is now no Object.valueOf left anywhere under samples/.

Test coverage

Added to the petstore test specs (kept from #21055):

  • Order.paymentMethod — a numeric (type: number) enum, covering the BigDecimal case.
  • Order.OrderStatus — a type: string enum with additionalProperties: false, covering the Object case.
  • enum_form_integer / enum_form_double form parameters on testEnumParameters.

All 800 sample configurations regenerate successfully.

Note on the failing Crystal check

Samples Crystal clients fails at shards install, before any generated code is compiled:

E: Unable to satisfy the following requirements:
- `ameba (1.7.0-dev)` required by `shard.yml`

modules/openapi-generator/src/main/resources/crystal/shard.mustache pins ameba to the prerelease 1.7.0-dev, which stopped resolving once Ameba 1.7.0 was released. This is unrelated to this PR; the job is simply triggered here because the shared petstore spec regenerates the Crystal sample. I left it untouched to keep this PR scoped, but it will need a separate fix in the template.

This PR closes #20188 and replaces #21055.

The Java enum templates wrapped every enum value with `{{dataType}}.valueOf(...)`.
That method does not exist for every possible data type (e.g. `BigDecimal` has no
`BigDecimal.valueOf(BigDecimal)` and `Object` has no `valueOf` at all), producing
code that does not compile.

`valueOf()` is now only emitted for types where it actually exists, i.e. it is
skipped for `isUri`, `isNumeric` and `isFreeFormObject` enum values. The wrapper
was originally introduced to fix Boolean enums (OpenAPITools#19815), which keeps working.

Templates updated:
- Java/modelInnerEnum.mustache
- Java/libraries/microprofile/enumClass.mustache
- JavaJaxRS/{spec,cxf,cxf-cdi,cxf-ext}/enumClass.mustache
- java-helidon/client/libraries/{mp,se}/enumClass.mustache
- java-helidon/server/libraries/mp/enumClass.mustache

Test coverage added to the petstore test specs: a numeric enum (`Order.paymentMethod`),
a string enum with `additionalProperties: false` (`Order.OrderStatus`) and integer /
double form enum parameters.

Fixes OpenAPITools#20188

Co-authored-by: Timon Link <timon.link@sbroker.de>
Co-authored-by: Martin <2026226+martin-mfg@users.noreply.github.com>

@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.

27 issues found across 265 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="samples/client/petstore/java/restclient-useSingleRequestParameter-static/src/main/java/org/openapitools/client/model/Order.java">

<violation number="1" location="samples/client/petstore/java/restclient-useSingleRequestParameter-static/src/main/java/org/openapitools/client/model/Order.java:132">
P2: When a payload uses `1.0` for `paymentMethod`, `PaymentMethodEnum.fromValue` rejects it against the enum value `1` because `BigDecimal.equals` compares scale. Compare numeric values with `compareTo` while retaining a null guard.</violation>
</file>

<file name="samples/server/petstore/java-helidon-server/v3/mp/src/main/java/org/openapitools/server/model/Order.java">

<violation number="1" location="samples/server/petstore/java-helidon-server/v3/mp/src/main/java/org/openapitools/server/model/Order.java:92">
P2: The MicroProfile `PaymentMethodEnum` serializes numeric values as JSON strings because `@JsonValue` annotates `toString()`, which returns `String`. Annotate the typed value accessor instead so `BigDecimal` values remain JSON numbers.</violation>

<violation number="2" location="samples/server/petstore/java-helidon-server/v3/mp/src/main/java/org/openapitools/server/model/Order.java:131">
P2: For the new numeric BigDecimal enum, fromValue() matches with b.value.equals(value), but BigDecimal.equals() also compares scale, not just numeric value (BigDecimal("1") is not equal to BigDecimal("1.0")). Since Jackson preserves the scale present in the JSON text, a paymentMethod value serialized with trailing zeros (e.g. 1.0 or 1.00) would not match NUMBER_1 and would throw IllegalArgumentException even though the value is numerically identical. Compare with compareTo() == 0 (or strip trailing zeros) so numeric equivalence is respected.</violation>
</file>

<file name="samples/client/petstore/java-helidon-client/v3/se/src/main/java/org/openapitools/client/api/FakeApiImpl.java">

<violation number="1" location="samples/client/petstore/java-helidon-client/v3/se/src/main/java/org/openapitools/client/api/FakeApiImpl.java:755">
P2: When a caller omits the optional `enumFormInteger` or `enumFormDouble` (both are @Nullable), the generated form body contains the literal `enum_form_integer=null` / `enum_form_double=null` because the StringJoiner concatenates the raw value without a null guard. Every other regenerated sample in this batch guards these params with `if (... != null)`. Add null checks (or conditionally add the pairs) in the helidon SE submit builder so absent optional params are not serialized as "null".</violation>
</file>

<file name="samples/server/petstore/java-helidon-server/v3/se/src/main/resources/META-INF/openapi.yml">

<violation number="1" location="samples/server/petstore/java-helidon-server/v3/se/src/main/resources/META-INF/openapi.yml:1488">
P2: `OrderStatus` declares an object schema but supplies string enum values and a string example, so no value satisfies the generated OpenAPI schema. Declare it as a string enum and use an enum value such as `PENDING` for the example.</violation>
</file>

<file name="samples/client/petstore/java/okhttp-gson/src/main/java/org/openapitools/client/model/Order.java">

<violation number="1" location="samples/client/petstore/java/okhttp-gson/src/main/java/org/openapitools/client/model/Order.java:166">
P2: When the API sends an equivalent numeric spelling such as `1.0`, `PaymentMethodEnum.fromValue` rejects it because `BigDecimal.equals` compares scale. Compare the values with `compareTo` instead.</violation>

<violation number="2" location="samples/client/petstore/java/okhttp-gson/src/main/java/org/openapitools/client/model/Order.java:459">
P2: When `paymentMethod` is non-primitive JSON, this branch skips the primitive check used for `status`; singleton arrays can pass `Order.validateJsonElement` as enum values. Add the same primitive-type guard before calling `PaymentMethodEnum.validateJsonElement`.</violation>
</file>

<file name="samples/client/petstore/java/vertx-supportVertxFuture/src/main/java/org/openapitools/client/model/Order.java">

<violation number="1" location="samples/client/petstore/java/vertx-supportVertxFuture/src/main/java/org/openapitools/client/model/Order.java:131">
P2: When JSON uses an equivalent representation such as `1.0`, `PaymentMethodEnum.fromValue` rejects it because `BigDecimal.equals` compares scale. Compare values with `compareTo` while handling null.</violation>
</file>

<file name="samples/server/petstore/java-helidon-server/v4/se-uac-group-by-file-path/src/main/java/org/openapitools/server/api/FakeService.java">

<violation number="1" location="samples/server/petstore/java-helidon-server/v4/se-uac-group-by-file-path/src/main/java/org/openapitools/server/api/FakeService.java:3032">
P2: When a client submits an equivalent numeric spelling such as `1.10` or `0`, this parser rejects it because `BigDecimal.equals` is scale-sensitive and `ValidatorUtils.check` calls `List.contains`. Normalize the parsed and allowed values, or compare them with `BigDecimal.compareTo`, before validation.</violation>
</file>

<file name="samples/client/petstore/java/apache-httpclient/src/main/java/org/openapitools/client/model/Order.java">

<violation number="1" location="samples/client/petstore/java/apache-httpclient/src/main/java/org/openapitools/client/model/Order.java:134">
P2: When a payload sends `paymentMethod` as `1.0`, `fromValue` rejects the valid numeric enum value because `BigDecimal.equals` is scale-sensitive. Compare `BigDecimal` values with `compareTo` and guard null before comparing.</violation>
</file>

<file name="samples/client/petstore/java/resteasy/src/main/java/org/openapitools/client/model/Order.java">

<violation number="1" location="samples/client/petstore/java/resteasy/src/main/java/org/openapitools/client/model/Order.java:131">
P2: When JSON sends this numeric enum as `1.0`, `PaymentMethodEnum.fromValue` rejects it because `BigDecimal.equals` compares scale. Match numeric values with `compareTo` after a null check.</violation>
</file>

<file name="samples/client/petstore/java/restclient-swagger2/src/main/java/org/openapitools/client/model/Order.java">

<violation number="1" location="samples/client/petstore/java/restclient-swagger2/src/main/java/org/openapitools/client/model/Order.java:133">
P2: When the API serializes an equivalent numeric value with a different scale, `PaymentMethodEnum.fromValue` rejects it because `BigDecimal.equals` distinguishes `1` from `1.0`. Compare with `compareTo` instead, while retaining a null guard.</violation>
</file>

<file name="samples/server/petstore/java-helidon-server/v4/mp/src/main/java/org/openapitools/server/model/Order.java">

<violation number="1" location="samples/server/petstore/java-helidon-server/v4/mp/src/main/java/org/openapitools/server/model/Order.java:108">
P2: When `Order.paymentMethod` is serialized, Jackson emits `"1"` rather than the numeric value required by the schema because `@JsonValue` is attached to `PaymentMethodEnum.toString()`. Move `@JsonValue` to the `BigDecimal value()` accessor and leave `toString()` unannotated.</violation>

<violation number="2" location="samples/server/petstore/java-helidon-server/v4/mp/src/main/java/org/openapitools/server/model/Order.java:131">
P2: When a client sends an equivalent numeric representation such as `1.0`, `fromValue` throws because `BigDecimal.equals` treats scale differences as unequal. Compare `BigDecimal` values with `compareTo(...) == 0` after handling null.</violation>
</file>

<file name="samples/server/petstore/java-wiremock/src/main/java/org/openapitools/mockserver/api/StoreApiMockServer.java">

<violation number="1" location="samples/server/petstore/java-wiremock/src/main/java/org/openapitools/mockserver/api/StoreApiMockServer.java:138">
P2: The new OrderStatus string enum (values PENDING/PROCESSING) generates sample value "{}" in the JSON samples and "UNDEFINED_EXAMPLE_VALUE" in the XML samples, neither of which is a valid enum member — unlike the adjacent "status" enum, which correctly produces "placed". The example generator is misclassifying the string enum that has additionalProperties:false as an object (ExampleGenerator returns "{}" / XmlExampleGenerator returns UNDEFINED_EXAMPLE_VALUE), so the mock-server responses expose invalid data that will fail clients validating against the Order schema. Make the generator return a real enum value for this case, or drop the placeholder fields from the samples.</violation>
</file>

<file name="samples/client/petstore/java/feign-hc5/src/main/java/org/openapitools/client/model/Order.java">

<violation number="1" location="samples/client/petstore/java/feign-hc5/src/main/java/org/openapitools/client/model/Order.java:131">
P2: PaymentMethodEnum.fromValue(BigDecimal) matches enum values with b.value.equals(value). BigDecimal.equals is scale-sensitive, so a numeric payload such as 1.0 or 2.00 won't match NUMBER_1 (new BigDecimal("1")) and throws IllegalArgumentException at deserialization even though the numbers are equal. Use compareTo for numeric enum comparison, e.g. b.value.compareTo(value) == 0, or normalize scale.</violation>
</file>

<file name="samples/client/petstore/crystal/src/petstore/models/order.cr">

<violation number="1" location="samples/client/petstore/crystal/src/petstore/models/order.cr:46">
P2: The generated enum validation for `order_status` compares the String array `["PENDING", "PROCESSING"]` against a `JSON::Any` value. `Array(String)#includes?(JSON::Any)` resolves to `String#==(JSON::Any)`, which has no overload in Crystal, so the generated Order model fails to compile. The field is JSON::Any because OrderStatus has `additionalProperties: false`, so the enum check is also semantically wrong for an object-typed property. Guard enum emission in the Crystal generator (partial_model_generic.mustache) to skip `enum:` for object/free-form (JSON::Any) types instead of emitting it for this newly added property.</violation>
</file>

<file name="samples/server/petstore/java-helidon-server/v4/mp/src/main/resources/META-INF/openapi.yml">

<violation number="1" location="samples/server/petstore/java-helidon-server/v4/mp/src/main/resources/META-INF/openapi.yml:1488">
P2: OrderStatus is `type: object` in this bundled openapi.yml but `type: string` in the canonical petstore spec that this sample's config (bin/configs/java-helidon-server-mp_4.yaml) uses as inputSpec. The checked-in generated code is an object enum, so the sample is internally consistent with type:object, but regenerating from the canonical spec would produce a string enum for OrderStatus (which emits valueOf), differing from what is committed. Align the canonical petstore spec's OrderStatus type with this sample (or regenerate the sample from the canonical spec) so the Object-case regression test is reproducible and the sample can be regenerated cleanly.</violation>
</file>

<file name="samples/client/petstore/java-helidon-client/v3/mp/src/main/java/org/openapitools/client/model/Order.java">

<violation number="1" location="samples/client/petstore/java-helidon-client/v3/mp/src/main/java/org/openapitools/client/model/Order.java:66">
P2: The newly added numeric inner enum PaymentMethodEnum cannot round-trip its wire value. Its constant names NUMBER_1/NUMBER_2 diverge from the spec values "1"/"2", and the java-helidon enumClass.mustache template emits no @JsonValue/@JsonCreator, so Jackson's name-based default serializes PaymentMethodEnum.NUMBER_1 as "NUMBER_1" and throws on deserializing "1". The standalone numeric enum OuterEnumInteger in the same sample carries @JsonValue/@JsonCreator and round-trips correctly, so the two are inconsistent. Add the @JsonValue/@JsonCreator (fromValue) pattern to the inner enum template, matching enumClass/standalone enums, so the new numeric enum test case is functional rather than compile-only.</violation>
</file>

<file name="samples/server/petstore/java-helidon-server/v4/se-uac/src/main/java/org/openapitools/server/api/FakeService.java">

<violation number="1" location="samples/server/petstore/java-helidon-server/v4/se-uac/src/main/java/org/openapitools/server/api/FakeService.java:2981">
P2: When a client serializes an equivalent numeric representation such as `0` or `1.10`, this validator rejects it because `BigDecimal.equals` considers scale. Compare numeric values with `compareTo` or normalize the parsed value and allowed values before calling `check`.</violation>
</file>

<file name="samples/client/petstore/java/apache-httpclient-jackson3/src/main/java/org/openapitools/client/model/Order.java">

<violation number="1" location="samples/client/petstore/java/apache-httpclient-jackson3/src/main/java/org/openapitools/client/model/Order.java:133">
P2: When JSON represents an allowed numeric enum with a different scale, `PaymentMethodEnum.fromValue` rejects it because `BigDecimal.equals` compares scale as well as value. Compare with `BigDecimal.compareTo` while retaining the null check.</violation>
</file>

<file name="samples/client/petstore/java/resttemplate/src/main/java/org/openapitools/client/model/Order.java">

<violation number="1" location="samples/client/petstore/java/resttemplate/src/main/java/org/openapitools/client/model/Order.java:132">
P2: When a response encodes this enum as `1.0` instead of `1`, `PaymentMethodEnum.fromValue` rejects it because `BigDecimal.equals` is scale-sensitive. Compare BigDecimal values numerically with `compareTo` while retaining the null guard.</violation>
</file>

<file name="samples/client/petstore/ruby-autoload/lib/petstore/models/order.rb">

<violation number="1" location="samples/client/petstore/ruby-autoload/lib/petstore/models/order.rb:148">
P1: When callers omit `payment_method`, `Order#initialize` raises `NameError` instead of applying the schema default because `PAYMENT_METHOD::N1` is not defined in this client. Assign the numeric default emitted by the schema, or generate the corresponding enum constant.</violation>
</file>

<file name="samples/client/petstore/java-helidon-client/v3/se/src/main/java/org/openapitools/client/model/Order.java">

<violation number="1" location="samples/client/petstore/java-helidon-client/v3/se/src/main/java/org/openapitools/client/model/Order.java:74">
P1: When `paymentMethod` is serialized by the generated Helidon client, Jackson sends `"NUMBER_1"` instead of numeric `1` because this new enum accessor lacks `@JsonValue`. Annotate the value accessor and add the matching creator so requests and responses use the declared numeric values.</violation>
</file>

<file name="samples/server/petstore/java-helidon-server/v4/se-uac-group-by-file-path/src/main/java/org/openapitools/server/model/Order.java">

<violation number="1" location="samples/server/petstore/java-helidon-server/v4/se-uac-group-by-file-path/src/main/java/org/openapitools/server/model/Order.java:133">
P2: When clients use the schema’s `OrderStatus` property, Jackson binds this model member as `orderStatus` because no annotation preserves the original name. Add `@JsonProperty("OrderStatus")` to this field or its accessors.</violation>
</file>

<file name="samples/server/petstore/java-helidon-server/v4/se-uac/src/main/java/org/openapitools/server/model/Order.java">

<violation number="1" location="samples/server/petstore/java-helidon-server/v4/se-uac/src/main/java/org/openapitools/server/model/Order.java:86">
P2: When a numeric enum arrives with a valid alternate JSON number representation such as `1.0`, this string comparison rejects it. Compare parsed `BigDecimal` values numerically instead of comparing their textual forms.</violation>

<violation number="2" location="samples/server/petstore/java-helidon-server/v4/se-uac/src/main/java/org/openapitools/server/model/Order.java:133">
P2: The added field changes the OpenAPI wire name from `OrderStatus` to `orderStatus`. Preserve the declared property name with an explicit Jackson/JSON-B property annotation so requests and responses use the schema name.</violation>
</file>

Note: This PR contains a large number of files. cubic selects up to 200 of the highest-priority eligible files for this review, so some files may not have been reviewed.

Re-trigger cubic

if attributes.key?(:'payment_method')
self.payment_method = attributes[:'payment_method']
else
self.payment_method = PAYMENT_METHOD::N1

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.

P1: When callers omit payment_method, Order#initialize raises NameError instead of applying the schema default because PAYMENT_METHOD::N1 is not defined in this client. Assign the numeric default emitted by the schema, or generate the corresponding enum constant.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At samples/client/petstore/ruby-autoload/lib/petstore/models/order.rb, line 148:

<comment>When callers omit `payment_method`, `Order#initialize` raises `NameError` instead of applying the schema default because `PAYMENT_METHOD::N1` is not defined in this client. Assign the numeric default emitted by the schema, or generate the corresponding enum constant.</comment>

<file context>
@@ -131,6 +141,16 @@ def initialize(attributes = {})
+      if attributes.key?(:'payment_method')
+        self.payment_method = attributes[:'payment_method']
+      else
+        self.payment_method = PAYMENT_METHOD::N1
+      end
+
</file context>
Suggested change
self.payment_method = PAYMENT_METHOD::N1
self.payment_method = 1

value = v;
}

public BigDecimal 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.

P1: When paymentMethod is serialized by the generated Helidon client, Jackson sends "NUMBER_1" instead of numeric 1 because this new enum accessor lacks @JsonValue. Annotate the value accessor and add the matching creator so requests and responses use the declared numeric values.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At samples/client/petstore/java-helidon-client/v3/se/src/main/java/org/openapitools/client/model/Order.java, line 74:

<comment>When `paymentMethod` is serialized by the generated Helidon client, Jackson sends `"NUMBER_1"` instead of numeric `1` because this new enum accessor lacks `@JsonValue`. Annotate the value accessor and add the matching creator so requests and responses use the declared numeric values.</comment>

<file context>
@@ -60,6 +61,58 @@ public String toString() {
+        value = v;
+    }
+
+    public BigDecimal value() {
+        return value;
+    }
</file context>


validates(status, String, true, enum: ["placed", "approved", "delivered"])
validates(payment_method, Float64, true, enum: [1, 2])
validates(order_status, JSON::Any, true, enum: ["PENDING", "PROCESSING"])

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: The generated enum validation for order_status compares the String array ["PENDING", "PROCESSING"] against a JSON::Any value. Array(String)#includes?(JSON::Any) resolves to String#==(JSON::Any), which has no overload in Crystal, so the generated Order model fails to compile. The field is JSON::Any because OrderStatus has additionalProperties: false, so the enum check is also semantically wrong for an object-typed property. Guard enum emission in the Crystal generator (partial_model_generic.mustache) to skip enum: for object/free-form (JSON::Any) types instead of emitting it for this newly added property.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At samples/client/petstore/crystal/src/petstore/models/order.cr, line 46:

<comment>The generated enum validation for `order_status` compares the String array `["PENDING", "PROCESSING"]` against a `JSON::Any` value. `Array(String)#includes?(JSON::Any)` resolves to `String#==(JSON::Any)`, which has no overload in Crystal, so the generated Order model fails to compile. The field is JSON::Any because OrderStatus has `additionalProperties: false`, so the enum check is also semantically wrong for an object-typed property. Guard enum emission in the Crystal generator (partial_model_generic.mustache) to skip `enum:` for object/free-form (JSON::Any) types instead of emitting it for this newly added property.</comment>

<file context>
@@ -33,11 +33,21 @@ module Petstore
+
     validates(status, String, true, enum: ["placed", "approved", "delivered"])
+    validates(payment_method, Float64, true, enum: [1, 2])
+    validates(order_status, JSON::Any, true, enum: ["PENDING", "PROCESSING"])
 
     # Initializes the object
</file context>

enum:
- PENDING
- PROCESSING
type: object

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: OrderStatus is type: object in this bundled openapi.yml but type: string in the canonical petstore spec that this sample's config (bin/configs/java-helidon-server-mp_4.yaml) uses as inputSpec. The checked-in generated code is an object enum, so the sample is internally consistent with type:object, but regenerating from the canonical spec would produce a string enum for OrderStatus (which emits valueOf), differing from what is committed. Align the canonical petstore spec's OrderStatus type with this sample (or regenerate the sample from the canonical spec) so the Object-case regression test is reproducible and the sample can be regenerated cleanly.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At samples/server/petstore/java-helidon-server/v4/mp/src/main/resources/META-INF/openapi.yml, line 1488:

<comment>OrderStatus is `type: object` in this bundled openapi.yml but `type: string` in the canonical petstore spec that this sample's config (bin/configs/java-helidon-server-mp_4.yaml) uses as inputSpec. The checked-in generated code is an object enum, so the sample is internally consistent with type:object, but regenerating from the canonical spec would produce a string enum for OrderStatus (which emits valueOf), differing from what is committed. Align the canonical petstore spec's OrderStatus type with this sample (or regenerate the sample from the canonical spec) so the Object-case regression test is reproducible and the sample can be regenerated cleanly.</comment>

<file context>
@@ -1465,6 +1467,25 @@ components:
+          enum:
+          - PENDING
+          - PROCESSING
+          type: object
       type: object
       xml:
</file context>


public enum PaymentMethodEnum {

NUMBER_1(new BigDecimal("1")), NUMBER_2(new BigDecimal("2"));

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: The newly added numeric inner enum PaymentMethodEnum cannot round-trip its wire value. Its constant names NUMBER_1/NUMBER_2 diverge from the spec values "1"/"2", and the java-helidon enumClass.mustache template emits no @JsonValue/@JsonCreator, so Jackson's name-based default serializes PaymentMethodEnum.NUMBER_1 as "NUMBER_1" and throws on deserializing "1". The standalone numeric enum OuterEnumInteger in the same sample carries @JsonValue/@JsonCreator and round-trips correctly, so the two are inconsistent. Add the @JsonValue/@JsonCreator (fromValue) pattern to the inner enum template, matching enumClass/standalone enums, so the new numeric enum test case is functional rather than compile-only.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At samples/client/petstore/java-helidon-client/v3/mp/src/main/java/org/openapitools/client/model/Order.java, line 66:

<comment>The newly added numeric inner enum PaymentMethodEnum cannot round-trip its wire value. Its constant names NUMBER_1/NUMBER_2 diverge from the spec values "1"/"2", and the java-helidon enumClass.mustache template emits no @JsonValue/@JsonCreator, so Jackson's name-based default serializes PaymentMethodEnum.NUMBER_1 as "NUMBER_1" and throws on deserializing "1". The standalone numeric enum OuterEnumInteger in the same sample carries @JsonValue/@JsonCreator and round-trips correctly, so the two are inconsistent. Add the @JsonValue/@JsonCreator (fromValue) pattern to the inner enum template, matching enumClass/standalone enums, so the new numeric enum test case is functional rather than compile-only.</comment>

<file context>
@@ -60,6 +61,58 @@ public String toString() {
 
+public enum PaymentMethodEnum {
+
+    NUMBER_1(new BigDecimal("1")), NUMBER_2(new BigDecimal("2"));
+
+    BigDecimal value;
</file context>


private Boolean complete = false;

public enum PaymentMethodEnum {

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: The MicroProfile PaymentMethodEnum serializes numeric values as JSON strings because @JsonValue annotates toString(), which returns String. Annotate the typed value accessor instead so BigDecimal values remain JSON numbers.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At samples/server/petstore/java-helidon-server/v3/mp/src/main/java/org/openapitools/server/model/Order.java, line 92:

<comment>The MicroProfile `PaymentMethodEnum` serializes numeric values as JSON strings because `@JsonValue` annotates `toString()`, which returns `String`. Annotate the typed value accessor instead so `BigDecimal` values remain JSON numbers.</comment>

<file context>
@@ -88,6 +89,110 @@ public static StatusEnum fromValue(String value) {
 
   private Boolean complete = false;
 
+public enum PaymentMethodEnum {
+
+    NUMBER_1(new BigDecimal("1")), NUMBER_2(new BigDecimal("2"));
</file context>

String formParams = new StringJoiner("&")
.add("enum_form_string_array=" + enumFormStringArray)
.add("enum_form_string=" + enumFormString)
.add("enum_form_integer=" + enumFormInteger)

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: When a caller omits the optional enumFormInteger or enumFormDouble (both are @nullable), the generated form body contains the literal enum_form_integer=null / enum_form_double=null because the StringJoiner concatenates the raw value without a null guard. Every other regenerated sample in this batch guards these params with if (... != null). Add null checks (or conditionally add the pairs) in the helidon SE submit builder so absent optional params are not serialized as "null".

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At samples/client/petstore/java-helidon-client/v3/se/src/main/java/org/openapitools/client/api/FakeApiImpl.java, line 755:

<comment>When a caller omits the optional `enumFormInteger` or `enumFormDouble` (both are @Nullable), the generated form body contains the literal `enum_form_integer=null` / `enum_form_double=null` because the StringJoiner concatenates the raw value without a null guard. Every other regenerated sample in this batch guards these params with `if (... != null)`. Add null checks (or conditionally add the pairs) in the helidon SE submit builder so absent optional params are not serialized as "null".</comment>

<file context>
@@ -742,12 +744,16 @@ protected WebClientRequestBuilder testEnumParametersRequestBuilder(List<String>
     String formParams = new StringJoiner("&")
             .add("enum_form_string_array=" + enumFormStringArray)
             .add("enum_form_string=" + enumFormString)
+            .add("enum_form_integer=" + enumFormInteger)
+            .add("enum_form_double=" + enumFormDouble)
             .toString();
</file context>

@jorgerod
jorgerod marked this pull request as draft September 2, 2026 12:54
jorgerod and others added 5 commits September 2, 2026 15:38
- Exclude `isUuid` from the `valueOf()` wrapper. `AbstractJavaCodegen.toEnumValue`
  already returns `UUID.fromString("...")` for UUID enums, so the templates were
  emitting `UUID.valueOf(UUID.fromString(...))`, which does not compile. This is
  the same class of bug this PR fixes and mirrors the existing `isUri` handling.
  Regenerating all 800 samples produces no output change, as no test fixture
  currently declares a UUID enum.

- Revert the Ameba version change in the Crystal sample. It was edited in the
  generated `shard.yml` only, while the value comes from `crystal/shard.mustache`,
  so it would have been reverted by `Samples up-to-date`. The Ameba `1.7.0-dev`
  resolution failure is a pre-existing breakage unrelated to this PR.

- Drop the `FakeApiTest.java` entries that were added to `.openapi-generator/FILES`.
  The generator never overwrites existing test files, so those entries are not
  reproducible on regeneration and would have failed `Samples up-to-date`.
@jorgerod
jorgerod marked this pull request as ready for review September 2, 2026 15:17

@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.

6 issues found across 292 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/enumClass.mustache">

<violation number="1" location="modules/openapi-generator/src/main/resources/Java/libraries/microprofile/enumClass.mustache:18">
P1: When an enum schema uses `format: date` or `date-time`, this condition still emits `dataType.valueOf(...)` even though the mapped Java date types do not provide `valueOf`, producing uncompilable generated enums. Handle `isDate` and `isDateTime` through a valid date parsing expression before suppressing the wrapper.</violation>
</file>

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

<violation number="1" location="modules/openapi-generator/src/main/resources/Java/modelInnerEnum.mustache:26">
P1: For inline enums with `date`, `date-time`, or string `number` formats, this condition still emits `dataType.valueOf(...)`, so generated Java models fail compilation because those types do not provide the required `valueOf` conversion. Handle these flags with their appropriate parse/constructor expressions instead of sending them through `valueOf`.</violation>
</file>

<file name="modules/openapi-generator/src/main/resources/java-helidon/client/libraries/mp/enumClass.mustache">

<violation number="1" location="modules/openapi-generator/src/main/resources/java-helidon/client/libraries/mp/enumClass.mustache:8">
P1: When an enum schema uses `format: date` or `date-time`, this condition still emits `{{dataType}}.valueOf(...)`; Java date types do not provide that method, so the generated Helidon enum does not compile. Handle date/time values with the appropriate parser or exclude them from the `valueOf` branch.</violation>
</file>

<file name="modules/openapi-generator/src/main/resources/JavaJaxRS/cxf/enumClass.mustache">

<violation number="1" location="modules/openapi-generator/src/main/resources/JavaJaxRS/cxf/enumClass.mustache:8">
P1: When an enum schema uses a date or date-time format, this condition still generates `dataType.valueOf(...)`, but Java date types do not provide `valueOf`, so generated code fails to compile. Exclude `isDate` and `isDateTime` alongside the existing unsupported-type flags.</violation>
</file>

<file name="modules/openapi-generator/src/main/resources/JavaJaxRS/cxf-cdi/enumClass.mustache">

<violation number="1" location="modules/openapi-generator/src/main/resources/JavaJaxRS/cxf-cdi/enumClass.mustache:8">
P1: When a date or date-time schema is declared as an enum, this template still emits `dataType.valueOf(...)`; Java date types such as `LocalDate` and `OffsetDateTime` have no `valueOf`, so the generated model fails to compile. Exclude `isDate` and `isDateTime` from the `valueOf` wrapper, or emit the appropriate date parser.</violation>
</file>

<file name="modules/openapi-generator/src/main/resources/java-helidon/client/libraries/se/enumClass.mustache">

<violation number="1" location="modules/openapi-generator/src/main/resources/java-helidon/client/libraries/se/enumClass.mustache:8">
P1: When an enum schema uses `format: date` or `format: date-time`, this condition still emits `LocalDate.valueOf(...)` or `OffsetDateTime.valueOf(...)`, which do not compile. Handle date/time enums with their parser (or exclude them from this wrapper) before generating the constructor argument.</violation>
</file>

Note: This PR contains a large number of files. cubic selects up to 200 of the highest-priority eligible files for this review, so some files may not have been reviewed.

Re-trigger cubic

{{/withXml}}
{{^withXml}}
{{#enumVars}}{{name}}({{^isUri}}{{dataType}}.valueOf({{/isUri}}{{{value}}}{{^isUri}}){{/isUri}}){{^-last}}, {{/-last}}{{#-last}};{{/-last}}{{/enumVars}}
{{#enumVars}}{{name}}({{^isUri}}{{^isUuid}}{{^isNumeric}}{{^isFreeFormObject}}{{dataType}}.valueOf({{/isFreeFormObject}}{{/isNumeric}}{{/isUuid}}{{/isUri}}{{{value}}}{{^isUri}}{{^isUuid}}{{^isNumeric}}{{^isFreeFormObject}}){{/isFreeFormObject}}{{/isNumeric}}{{/isUuid}}{{/isUri}}){{^-last}}, {{/-last}}{{#-last}};{{/-last}}{{/enumVars}}

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.

P1: When an enum schema uses format: date or date-time, this condition still emits dataType.valueOf(...) even though the mapped Java date types do not provide valueOf, producing uncompilable generated enums. Handle isDate and isDateTime through a valid date parsing expression before suppressing the wrapper.

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/enumClass.mustache, line 18:

<comment>When an enum schema uses `format: date` or `date-time`, this condition still emits `dataType.valueOf(...)` even though the mapped Java date types do not provide `valueOf`, producing uncompilable generated enums. Handle `isDate` and `isDateTime` through a valid date parsing expression before suppressing the wrapper.</comment>

<file context>
@@ -12,10 +12,10 @@
     {{/withXml}}
     {{^withXml}}
-    {{#enumVars}}{{name}}({{^isUri}}{{dataType}}.valueOf({{/isUri}}{{{value}}}{{^isUri}}){{/isUri}}){{^-last}}, {{/-last}}{{#-last}};{{/-last}}{{/enumVars}}
+    {{#enumVars}}{{name}}({{^isUri}}{{^isUuid}}{{^isNumeric}}{{^isFreeFormObject}}{{dataType}}.valueOf({{/isFreeFormObject}}{{/isNumeric}}{{/isUuid}}{{/isUri}}{{{value}}}{{^isUri}}{{^isUuid}}{{^isNumeric}}{{^isFreeFormObject}}){{/isFreeFormObject}}{{/isNumeric}}{{/isUuid}}{{/isUri}}){{^-last}}, {{/-last}}{{#-last}};{{/-last}}{{/enumVars}}
     {{/withXml}}
     {{/allowableValues}}
</file context>

@XmlEnumValue({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}})
{{/withXml}}
{{{name}}}({{^isUri}}{{dataType}}.valueOf({{/isUri}}{{{value}}}{{^isUri}}){{/isUri}}){{^-last}},
{{{name}}}({{^isUri}}{{^isUuid}}{{^isNumeric}}{{^isFreeFormObject}}{{dataType}}.valueOf({{/isFreeFormObject}}{{/isNumeric}}{{/isUuid}}{{/isUri}}{{{value}}}{{^isUri}}{{^isUuid}}{{^isNumeric}}{{^isFreeFormObject}}){{/isFreeFormObject}}{{/isNumeric}}{{/isUuid}}{{/isUri}}){{^-last}},

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.

P1: For inline enums with date, date-time, or string number formats, this condition still emits dataType.valueOf(...), so generated Java models fail compilation because those types do not provide the required valueOf conversion. Handle these flags with their appropriate parse/constructor expressions instead of sending them through valueOf.

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/modelInnerEnum.mustache, line 26:

<comment>For inline enums with `date`, `date-time`, or string `number` formats, this condition still emits `dataType.valueOf(...)`, so generated Java models fail compilation because those types do not provide the required `valueOf` conversion. Handle these flags with their appropriate parse/constructor expressions instead of sending them through `valueOf`.</comment>

<file context>
@@ -23,7 +23,7 @@
     @XmlEnumValue({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}})
     {{/withXml}}
-    {{{name}}}({{^isUri}}{{dataType}}.valueOf({{/isUri}}{{{value}}}{{^isUri}}){{/isUri}}){{^-last}},
+    {{{name}}}({{^isUri}}{{^isUuid}}{{^isNumeric}}{{^isFreeFormObject}}{{dataType}}.valueOf({{/isFreeFormObject}}{{/isNumeric}}{{/isUuid}}{{/isUri}}{{{value}}}{{^isUri}}{{^isUuid}}{{^isNumeric}}{{^isFreeFormObject}}){{/isFreeFormObject}}{{/isNumeric}}{{/isUuid}}{{/isUri}}){{^-last}},
     {{/-last}}{{#-last}};{{/-last}}
       {{/enumVars}}
</file context>


{{#allowableValues}}
{{#enumVars}}{{name}}({{dataType}}.valueOf({{{value}}})){{^-last}}, {{/-last}}{{#-last}};{{/-last}}{{/enumVars}}
{{#enumVars}}{{name}}({{^isUri}}{{^isUuid}}{{^isNumeric}}{{^isFreeFormObject}}{{dataType}}.valueOf({{/isFreeFormObject}}{{/isNumeric}}{{/isUuid}}{{/isUri}}{{{value}}}{{^isUri}}{{^isUuid}}{{^isNumeric}}{{^isFreeFormObject}}){{/isFreeFormObject}}{{/isNumeric}}{{/isUuid}}{{/isUri}}){{^-last}}, {{/-last}}{{#-last}};{{/-last}}{{/enumVars}}

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.

P1: When an enum schema uses format: date or date-time, this condition still emits {{dataType}}.valueOf(...); Java date types do not provide that method, so the generated Helidon enum does not compile. Handle date/time values with the appropriate parser or exclude them from the valueOf branch.

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-helidon/client/libraries/mp/enumClass.mustache, line 8:

<comment>When an enum schema uses `format: date` or `date-time`, this condition still emits `{{dataType}}.valueOf(...)`; Java date types do not provide that method, so the generated Helidon enum does not compile. Handle date/time values with the appropriate parser or exclude them from the `valueOf` branch.</comment>

<file context>
@@ -5,7 +5,7 @@
 
     {{#allowableValues}}
-    {{#enumVars}}{{name}}({{dataType}}.valueOf({{{value}}})){{^-last}}, {{/-last}}{{#-last}};{{/-last}}{{/enumVars}}
+    {{#enumVars}}{{name}}({{^isUri}}{{^isUuid}}{{^isNumeric}}{{^isFreeFormObject}}{{dataType}}.valueOf({{/isFreeFormObject}}{{/isNumeric}}{{/isUuid}}{{/isUri}}{{{value}}}{{^isUri}}{{^isUuid}}{{^isNumeric}}{{^isFreeFormObject}}){{/isFreeFormObject}}{{/isNumeric}}{{/isUuid}}{{/isUri}}){{^-last}}, {{/-last}}{{#-last}};{{/-last}}{{/enumVars}}
     {{/allowableValues}}
 
</file context>


{{#allowableValues}}
{{#enumVars}}{{#withXml}}@XmlEnumValue({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}) {{/withXml}}{{name}}({{dataType}}.valueOf({{{value}}})){{^-last}}, {{/-last}}{{#-last}};{{/-last}}{{/enumVars}}
{{#enumVars}}{{#withXml}}@XmlEnumValue({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}) {{/withXml}}{{name}}({{^isUri}}{{^isUuid}}{{^isNumeric}}{{^isFreeFormObject}}{{dataType}}.valueOf({{/isFreeFormObject}}{{/isNumeric}}{{/isUuid}}{{/isUri}}{{{value}}}{{^isUri}}{{^isUuid}}{{^isNumeric}}{{^isFreeFormObject}}){{/isFreeFormObject}}{{/isNumeric}}{{/isUuid}}{{/isUri}}){{^-last}}, {{/-last}}{{#-last}};{{/-last}}{{/enumVars}}

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.

P1: When an enum schema uses a date or date-time format, this condition still generates dataType.valueOf(...), but Java date types do not provide valueOf, so generated code fails to compile. Exclude isDate and isDateTime alongside the existing unsupported-type flags.

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/JavaJaxRS/cxf/enumClass.mustache, line 8:

<comment>When an enum schema uses a date or date-time format, this condition still generates `dataType.valueOf(...)`, but Java date types do not provide `valueOf`, so generated code fails to compile. Exclude `isDate` and `isDateTime` alongside the existing unsupported-type flags.</comment>

<file context>
@@ -5,7 +5,7 @@
 
     {{#allowableValues}}
-{{#enumVars}}{{#withXml}}@XmlEnumValue({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}) {{/withXml}}{{name}}({{dataType}}.valueOf({{{value}}})){{^-last}}, {{/-last}}{{#-last}};{{/-last}}{{/enumVars}}
+{{#enumVars}}{{#withXml}}@XmlEnumValue({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}) {{/withXml}}{{name}}({{^isUri}}{{^isUuid}}{{^isNumeric}}{{^isFreeFormObject}}{{dataType}}.valueOf({{/isFreeFormObject}}{{/isNumeric}}{{/isUuid}}{{/isUri}}{{{value}}}{{^isUri}}{{^isUuid}}{{^isNumeric}}{{^isFreeFormObject}}){{/isFreeFormObject}}{{/isNumeric}}{{/isUuid}}{{/isUri}}){{^-last}}, {{/-last}}{{#-last}};{{/-last}}{{/enumVars}}
     {{/allowableValues}}
 
</file context>
Suggested change
{{#enumVars}}{{#withXml}}@XmlEnumValue({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}) {{/withXml}}{{name}}({{^isUri}}{{^isUuid}}{{^isNumeric}}{{^isFreeFormObject}}{{dataType}}.valueOf({{/isFreeFormObject}}{{/isNumeric}}{{/isUuid}}{{/isUri}}{{{value}}}{{^isUri}}{{^isUuid}}{{^isNumeric}}{{^isFreeFormObject}}){{/isFreeFormObject}}{{/isNumeric}}{{/isUuid}}{{/isUri}}){{^-last}}, {{/-last}}{{#-last}};{{/-last}}{{/enumVars}}
{{#enumVars}}{{#withXml}}@XmlEnumValue({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}) {{/withXml}}{{name}}({{^isUri}}{{^isUuid}}{{^isNumeric}}{{^isFreeFormObject}}{{^isDate}}{{^isDateTime}}{{dataType}}.valueOf({{/isDateTime}}{{/isDate}}{{/isFreeFormObject}}{{/isNumeric}}{{/isUuid}}{{/isUri}}{{{value}}}{{^isUri}}{{^isUuid}}{{^isNumeric}}{{^isFreeFormObject}}{{^isDate}}{{^isDateTime}}){{/isDateTime}}{{/isDate}}{{/isFreeFormObject}}{{/isNumeric}}{{/isUuid}}{{/isUri}}){{^-last}}, {{/-last}}{{#-last}};{{/-last}}{{/enumVars}}


{{#allowableValues}}
{{#enumVars}}{{#withXml}}@XmlEnumValue({{^isString}}"{{/isString}}{{{value}}}{{^isString}}"{{/isString}}) {{/withXml}}@JsonProperty({{^isString}}"{{/isString}}{{{value}}}{{^isString}}"{{/isString}}) {{name}}({{dataType}}.valueOf({{{value}}})){{^-last}}, {{/-last}}{{#-last}};{{/-last}}{{/enumVars}}
{{#enumVars}}{{#withXml}}@XmlEnumValue({{^isString}}"{{/isString}}{{{value}}}{{^isString}}"{{/isString}}) {{/withXml}}@JsonProperty({{^isString}}"{{/isString}}{{{value}}}{{^isString}}"{{/isString}}) {{name}}({{^isUri}}{{^isUuid}}{{^isNumeric}}{{^isFreeFormObject}}{{dataType}}.valueOf({{/isFreeFormObject}}{{/isNumeric}}{{/isUuid}}{{/isUri}}{{{value}}}{{^isUri}}{{^isUuid}}{{^isNumeric}}{{^isFreeFormObject}}){{/isFreeFormObject}}{{/isNumeric}}{{/isUuid}}{{/isUri}}){{^-last}}, {{/-last}}{{#-last}};{{/-last}}{{/enumVars}}

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.

P1: When a date or date-time schema is declared as an enum, this template still emits dataType.valueOf(...); Java date types such as LocalDate and OffsetDateTime have no valueOf, so the generated model fails to compile. Exclude isDate and isDateTime from the valueOf wrapper, or emit the appropriate date parser.

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/JavaJaxRS/cxf-cdi/enumClass.mustache, line 8:

<comment>When a date or date-time schema is declared as an enum, this template still emits `dataType.valueOf(...)`; Java date types such as `LocalDate` and `OffsetDateTime` have no `valueOf`, so the generated model fails to compile. Exclude `isDate` and `isDateTime` from the `valueOf` wrapper, or emit the appropriate date parser.</comment>

<file context>
@@ -5,7 +5,7 @@
 
     {{#allowableValues}}
-    {{#enumVars}}{{#withXml}}@XmlEnumValue({{^isString}}"{{/isString}}{{{value}}}{{^isString}}"{{/isString}}) {{/withXml}}@JsonProperty({{^isString}}"{{/isString}}{{{value}}}{{^isString}}"{{/isString}}) {{name}}({{dataType}}.valueOf({{{value}}})){{^-last}}, {{/-last}}{{#-last}};{{/-last}}{{/enumVars}}
+    {{#enumVars}}{{#withXml}}@XmlEnumValue({{^isString}}"{{/isString}}{{{value}}}{{^isString}}"{{/isString}}) {{/withXml}}@JsonProperty({{^isString}}"{{/isString}}{{{value}}}{{^isString}}"{{/isString}}) {{name}}({{^isUri}}{{^isUuid}}{{^isNumeric}}{{^isFreeFormObject}}{{dataType}}.valueOf({{/isFreeFormObject}}{{/isNumeric}}{{/isUuid}}{{/isUri}}{{{value}}}{{^isUri}}{{^isUuid}}{{^isNumeric}}{{^isFreeFormObject}}){{/isFreeFormObject}}{{/isNumeric}}{{/isUuid}}{{/isUri}}){{^-last}}, {{/-last}}{{#-last}};{{/-last}}{{/enumVars}}
     {{/allowableValues}}
 
</file context>


{{#allowableValues}}
{{#enumVars}}{{name}}({{dataType}}.valueOf({{{value}}})){{^-last}}, {{/-last}}{{#-last}};{{/-last}}{{/enumVars}}
{{#enumVars}}{{name}}({{^isUri}}{{^isUuid}}{{^isNumeric}}{{^isFreeFormObject}}{{dataType}}.valueOf({{/isFreeFormObject}}{{/isNumeric}}{{/isUuid}}{{/isUri}}{{{value}}}{{^isUri}}{{^isUuid}}{{^isNumeric}}{{^isFreeFormObject}}){{/isFreeFormObject}}{{/isNumeric}}{{/isUuid}}{{/isUri}}){{^-last}}, {{/-last}}{{#-last}};{{/-last}}{{/enumVars}}

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.

P1: When an enum schema uses format: date or format: date-time, this condition still emits LocalDate.valueOf(...) or OffsetDateTime.valueOf(...), which do not compile. Handle date/time enums with their parser (or exclude them from this wrapper) before generating the constructor argument.

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-helidon/client/libraries/se/enumClass.mustache, line 8:

<comment>When an enum schema uses `format: date` or `format: date-time`, this condition still emits `LocalDate.valueOf(...)` or `OffsetDateTime.valueOf(...)`, which do not compile. Handle date/time enums with their parser (or exclude them from this wrapper) before generating the constructor argument.</comment>

<file context>
@@ -5,7 +5,7 @@
 
     {{#allowableValues}}
-    {{#enumVars}}{{name}}({{dataType}}.valueOf({{{value}}})){{^-last}}, {{/-last}}{{#-last}};{{/-last}}{{/enumVars}}
+    {{#enumVars}}{{name}}({{^isUri}}{{^isUuid}}{{^isNumeric}}{{^isFreeFormObject}}{{dataType}}.valueOf({{/isFreeFormObject}}{{/isNumeric}}{{/isUuid}}{{/isUri}}{{{value}}}{{^isUri}}{{^isUuid}}{{^isNumeric}}{{^isFreeFormObject}}){{/isFreeFormObject}}{{/isNumeric}}{{/isUuid}}{{/isUri}}){{^-last}}, {{/-last}}{{#-last}};{{/-last}}{{/enumVars}}
     {{/allowableValues}}
 
</file context>

…withXml

Two additional compile failures surfaced by the new PaymentMethodEnum (BigDecimal)
and OrderStatusEnum (Object) test fixtures, both unrelated to the valueOf() fix
but exposed by the same regression tests:

1. JSON-B serializer: `generator.write(obj.value)` requires an overload matching
   the static type of `obj.value`. `jakarta.json.stream.JsonGenerator` has no
   `write(Object)` overload, so any enum backed by a free-form/Object dataType
   (e.g. OrderStatusEnum, `additionalProperties: false`) failed to compile with:

     no suitable method found for write(java.lang.Object)

   Fixed by writing `String.valueOf(obj.value)` when `isFreeFormObject`, in every
   template with this JSON-B `Serializer` (Java, java-helidon client/server,
   microprofile, for both inner and standalone enums).

2. `@XmlEnumValue`: the annotation requires a compile-time constant `String`.
   The existing quoting logic only handles `isInteger`/`isDouble`/`isLong`/
   `isFloat`. For any other numeric format (plain `type: number`, dataType
   `BigDecimal`), `{{{value}}}` is `new BigDecimal("1")` — an expression, not a
   constant — which is invalid as an annotation argument:

     expression not allowed as annotation value

   The same applies to `isUri` (`URI.create(...)`) and `isUuid`
   (`UUID.fromString(...)`), which were never exercised with `withXml` before.
   Fixed by omitting `@XmlEnumValue` for `isUri`/`isUuid`/`isNumber` enums;
   JAXB falls back to the enum constant name, which still compiles.

Regenerating all 800 samples changes only the 3 previously-broken outputs
(microprofile-rest-client, microprofile-rest-client-3.0, resttemplate-withXml);
all three now compile (`mvn compile`).

@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.

10 issues found across 23 files (changes from recent commits).

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/enumClass.mustache">

<violation number="1" location="modules/openapi-generator/src/main/resources/Java/libraries/microprofile/enumClass.mustache:15">
P2: When an XML-enabled `type: number` enum is generated, this section removes `@XmlEnumValue`, so JAXB maps `NUMBER_1`/`NUMBER_2` instead of the wire values `1`/`2`. Keep the annotation for numeric enums and quote the numeric literal for its required `String value()` annotation parameter.</violation>
</file>

<file name="modules/openapi-generator/src/main/resources/java-helidon/server/libraries/mp/modelEnum.mustache">

<violation number="1" location="modules/openapi-generator/src/main/resources/java-helidon/server/libraries/mp/modelEnum.mustache:24">
P2: When `withXml` is enabled for a generic numeric enum, this guard drops `@XmlEnumValue`, so JAXB serializes the generated constant name instead of the numeric enum value. Keep the annotation for `isNumber` and emit its value as a quoted XML lexical string.</violation>
</file>

<file name="modules/openapi-generator/src/main/resources/java-helidon/client/libraries/mp/modelInnerEnum.mustache">

<violation number="1" location="modules/openapi-generator/src/main/resources/java-helidon/client/libraries/mp/modelInnerEnum.mustache:24">
P2: For XML `type: number` enums, `isNumber` suppresses `@XmlEnumValue`, so JAXB emits the Java constant name instead of the schema literal. Keep the annotation and quote the numeric value.</violation>
</file>

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

<violation number="1" location="modules/openapi-generator/src/main/resources/Java/modelInnerEnum.mustache:24">
P2: When `withXml` is enabled for an unformatted `number` enum, this suppresses `@XmlEnumValue` while retaining `@XmlEnum(BigDecimal.class),` so XML serialization loses the declared numeric lexical value and can emit `NUMBER_1` instead of `1`. Quote `isNumber` values and retain the annotation rather than dropping the mapping.</violation>
</file>

<file name="modules/openapi-generator/src/main/resources/Java/libraries/okhttp-gson/modelEnum.mustache">

<violation number="1" location="modules/openapi-generator/src/main/resources/Java/libraries/okhttp-gson/modelEnum.mustache:26">
P2: When `withXml` is enabled for an unformatted `type: number` enum, this condition removes `@XmlEnumValue`, so JAXB loses the mapping from generated constant names to numeric XML values. Keep the annotation for `isNumber` and quote its literal value, while retaining the URI/UUID exclusions.</violation>
</file>

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

<violation number="1" location="modules/openapi-generator/src/main/resources/Java/libraries/microprofile/enumOuterClass.mustache:54">
P2: When an enum value is a free-form object, this serializer emits the object's Java string representation as a JSON string, losing its object structure. Serialize the value through the JSON-B `SerializationContext` instead of converting it to `String`.</violation>
</file>

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

<violation number="1" location="modules/openapi-generator/src/main/resources/Java/modelEnum.mustache:37">
P1: For `withXml` and an unformatted `type: number` enum, `isNumber` suppresses `@XmlEnumValue`, so XML no longer maps values such as `1.1` to the enum constant. Keep the annotation for numeric enums and quote `isNumber` values; exclude only URI/UUID expressions that cannot be annotation literals.</violation>
</file>

<file name="modules/openapi-generator/src/main/resources/JavaJaxRS/cxf-ext/enumClass.mustache">

<violation number="1" location="modules/openapi-generator/src/main/resources/JavaJaxRS/cxf-ext/enumClass.mustache:8">
P2: When `withXml` is enabled for an unformatted `type: number` enum, this guard removes every `@XmlEnumValue`. Because the enum still declares `@XmlEnum({{dataType}}.class)`, JAXB falls back to Java constant names instead of numeric XML values; keep the XML value annotation for numeric enums.</violation>
</file>

<file name="modules/openapi-generator/src/main/resources/Java/libraries/okhttp-gson/modelInnerEnum.mustache">

<violation number="1" location="modules/openapi-generator/src/main/resources/Java/libraries/okhttp-gson/modelInnerEnum.mustache:18">
P2: For Object-type enums (isFreeFormObject, e.g. type: object with additionalProperties: false), the new guard emits @XmlEnumValue because isNumber/isUri/isUuid are all false. The value is only quoted for integer/double/long/float, so an Object enum produces the unquoted @XmlEnumValue(abc), a compile error in the generated Java when withXml is on. Add {{^isFreeFormObject}} to the guard, matching the isFreeFormObject condition the PR applies to the enumClass templates.</violation>
</file>

<file name="modules/openapi-generator/src/main/resources/java-micronaut/common/model/modelEnum.mustache">

<violation number="1" location="modules/openapi-generator/src/main/resources/java-micronaut/common/model/modelEnum.mustache:24">
P2: When `withXml` is enabled for number, URI, or UUID enums, this suppresses `@XmlEnumValue` and makes JAXB use the Java enum constant name instead of the OpenAPI value. Preserve the XML lexical value in a compile-time string, adding raw enum-value metadata if needed, rather than dropping the annotation.</violation>
</file>

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

Re-trigger cubic

{{/enumDescription}}
{{#withXml}}
@XmlEnumValue({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}})
{{^isUri}}{{^isUuid}}{{^isNumber}}@XmlEnumValue({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}){{/isNumber}}{{/isUuid}}{{/isUri}}

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.

P1: For withXml and an unformatted type: number enum, isNumber suppresses @XmlEnumValue, so XML no longer maps values such as 1.1 to the enum constant. Keep the annotation for numeric enums and quote isNumber values; exclude only URI/UUID expressions that cannot be annotation literals.

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/modelEnum.mustache, line 37:

<comment>For `withXml` and an unformatted `type: number` enum, `isNumber` suppresses `@XmlEnumValue`, so XML no longer maps values such as `1.1` to the enum constant. Keep the annotation for numeric enums and quote `isNumber` values; exclude only URI/UUID expressions that cannot be annotation literals.</comment>

<file context>
@@ -34,7 +34,7 @@ import java.net.URI;
      {{/enumDescription}}
   {{#withXml}}
-  @XmlEnumValue({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}})
+  {{^isUri}}{{^isUuid}}{{^isNumber}}@XmlEnumValue({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}){{/isNumber}}{{/isUuid}}{{/isUri}}
   {{/withXml}}
   {{{name}}}({{{value}}}){{^-last}},
</file context>
Suggested change
{{^isUri}}{{^isUuid}}{{^isNumber}}@XmlEnumValue({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}){{/isNumber}}{{/isUuid}}{{/isUri}}
{{^isUri}}{{^isUuid}}@XmlEnumValue({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{#isNumber}}"{{/isNumber}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{#isNumber}}"{{/isNumber}}){{/isUuid}}{{/isUri}}

{{#allowableValues}}
{{#withXml}}
{{#enumVars}}@XmlEnumValue({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}) {{name}}({{dataType}}.valueOf({{{value}}})){{^-last}}, {{/-last}}{{#-last}};{{/-last}}{{/enumVars}}
{{#enumVars}}{{^isUri}}{{^isUuid}}{{^isNumber}}@XmlEnumValue({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}){{/isNumber}}{{/isUuid}}{{/isUri}} {{name}}({{^isUri}}{{^isUuid}}{{^isNumeric}}{{^isFreeFormObject}}{{dataType}}.valueOf({{/isFreeFormObject}}{{/isNumeric}}{{/isUuid}}{{/isUri}}{{{value}}}{{^isUri}}{{^isUuid}}{{^isNumeric}}{{^isFreeFormObject}}){{/isFreeFormObject}}{{/isNumeric}}{{/isUuid}}{{/isUri}}){{^-last}}, {{/-last}}{{#-last}};{{/-last}}{{/enumVars}}

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: When an XML-enabled type: number enum is generated, this section removes @XmlEnumValue, so JAXB maps NUMBER_1/NUMBER_2 instead of the wire values 1/2. Keep the annotation for numeric enums and quote the numeric literal for its required String value() annotation parameter.

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/enumClass.mustache, line 15:

<comment>When an XML-enabled `type: number` enum is generated, this section removes `@XmlEnumValue`, so JAXB maps `NUMBER_1`/`NUMBER_2` instead of the wire values `1`/`2`. Keep the annotation for numeric enums and quote the numeric literal for its required `String value()` annotation parameter.</comment>

<file context>
@@ -12,7 +12,7 @@
     {{#allowableValues}}
     {{#withXml}}
-    {{#enumVars}}@XmlEnumValue({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}) {{name}}({{^isUri}}{{^isUuid}}{{^isNumeric}}{{^isFreeFormObject}}{{dataType}}.valueOf({{/isFreeFormObject}}{{/isNumeric}}{{/isUuid}}{{/isUri}}{{{value}}}{{^isUri}}{{^isUuid}}{{^isNumeric}}{{^isFreeFormObject}}){{/isFreeFormObject}}{{/isNumeric}}{{/isUuid}}{{/isUri}}){{^-last}}, {{/-last}}{{#-last}};{{/-last}}{{/enumVars}}
+    {{#enumVars}}{{^isUri}}{{^isUuid}}{{^isNumber}}@XmlEnumValue({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}){{/isNumber}}{{/isUuid}}{{/isUri}} {{name}}({{^isUri}}{{^isUuid}}{{^isNumeric}}{{^isFreeFormObject}}{{dataType}}.valueOf({{/isFreeFormObject}}{{/isNumeric}}{{/isUuid}}{{/isUri}}{{{value}}}{{^isUri}}{{^isUuid}}{{^isNumeric}}{{^isFreeFormObject}}){{/isFreeFormObject}}{{/isNumeric}}{{/isUuid}}{{/isUri}}){{^-last}}, {{/-last}}{{#-last}};{{/-last}}{{/enumVars}}
     {{/withXml}}
     {{^withXml}}
</file context>

{{/enumDescription}}
{{#withXml}}
@XmlEnumValue({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}})
{{^isUri}}{{^isUuid}}{{^isNumber}}@XmlEnumValue({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}){{/isNumber}}{{/isUuid}}{{/isUri}}

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: When withXml is enabled for a generic numeric enum, this guard drops @XmlEnumValue, so JAXB serializes the generated constant name instead of the numeric enum value. Keep the annotation for isNumber and emit its value as a quoted XML lexical string.

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-helidon/server/libraries/mp/modelEnum.mustache, line 24:

<comment>When `withXml` is enabled for a generic numeric enum, this guard drops `@XmlEnumValue`, so JAXB serializes the generated constant name instead of the numeric enum value. Keep the annotation for `isNumber` and emit its value as a quoted XML lexical string.</comment>

<file context>
@@ -21,7 +21,7 @@
     {{/enumDescription}}
     {{#withXml}}
-    @XmlEnumValue({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}})
+    {{^isUri}}{{^isUuid}}{{^isNumber}}@XmlEnumValue({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}){{/isNumber}}{{/isUuid}}{{/isUri}}
     {{/withXml}}
     {{{name}}}({{{value}}}){{^-last}},
</file context>

{{/enumDescription}}
{{#withXml}}
@XmlEnumValue({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}})
{{^isUri}}{{^isUuid}}{{^isNumber}}@XmlEnumValue({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}){{/isNumber}}{{/isUuid}}{{/isUri}}

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: For XML type: number enums, isNumber suppresses @XmlEnumValue, so JAXB emits the Java constant name instead of the schema literal. Keep the annotation and quote the numeric value.

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-helidon/client/libraries/mp/modelInnerEnum.mustache, line 24:

<comment>For XML `type: number` enums, `isNumber` suppresses `@XmlEnumValue`, so JAXB emits the Java constant name instead of the schema literal. Keep the annotation and quote the numeric value.</comment>

<file context>
@@ -21,7 +21,7 @@
     {{/enumDescription}}
     {{#withXml}}
-    @XmlEnumValue({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}})
+    {{^isUri}}{{^isUuid}}{{^isNumber}}@XmlEnumValue({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}){{/isNumber}}{{/isUuid}}{{/isUri}}
     {{/withXml}}
     {{{name}}}({{{value}}}){{^-last}},
</file context>
Suggested change
{{^isUri}}{{^isUuid}}{{^isNumber}}@XmlEnumValue({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}){{/isNumber}}{{/isUuid}}{{/isUri}}
{{^isUri}}{{^isUuid}}@XmlEnumValue({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{#isNumber}}"{{/isNumber}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{#isNumber}}"{{/isNumber}}){{/isUuid}}{{/isUri}}

{{/enumDescription}}
{{#withXml}}
@XmlEnumValue({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}})
{{^isUri}}{{^isUuid}}{{^isNumber}}@XmlEnumValue({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}){{/isNumber}}{{/isUuid}}{{/isUri}}

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: When withXml is enabled for an unformatted number enum, this suppresses @XmlEnumValue while retaining @XmlEnum(BigDecimal.class), so XML serialization loses the declared numeric lexical value and can emit NUMBER_1 instead of 1. Quote isNumber values and retain the annotation rather than dropping the mapping.

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/modelInnerEnum.mustache, line 24:

<comment>When `withXml` is enabled for an unformatted `number` enum, this suppresses `@XmlEnumValue` while retaining `@XmlEnum(BigDecimal.class),` so XML serialization loses the declared numeric lexical value and can emit `NUMBER_1` instead of `1`. Quote `isNumber` values and retain the annotation rather than dropping the mapping.</comment>

<file context>
@@ -21,7 +21,7 @@
     {{/enumDescription}}
     {{#withXml}}
-    @XmlEnumValue({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}})
+    {{^isUri}}{{^isUuid}}{{^isNumber}}@XmlEnumValue({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}){{/isNumber}}{{/isUuid}}{{/isUri}}
     {{/withXml}}
     {{{name}}}({{^isUri}}{{^isUuid}}{{^isNumeric}}{{^isFreeFormObject}}{{dataType}}.valueOf({{/isFreeFormObject}}{{/isNumeric}}{{/isUuid}}{{/isUri}}{{{value}}}{{^isUri}}{{^isUuid}}{{^isNumeric}}{{^isFreeFormObject}}){{/isFreeFormObject}}{{/isNumeric}}{{/isUuid}}{{/isUri}}){{^-last}},
</file context>
Suggested change
{{^isUri}}{{^isUuid}}{{^isNumber}}@XmlEnumValue({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}){{/isNumber}}{{/isUuid}}{{/isUri}}
{{^isUri}}{{^isUuid}}@XmlEnumValue({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{#isNumber}}"{{/isNumber}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{#isNumber}}"{{/isNumber}}){{/isUuid}}{{/isUri}}

{{/enumDescription}}
{{#withXml}}
@XmlEnumValue({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}})
{{^isUri}}{{^isUuid}}{{^isNumber}}@XmlEnumValue({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}){{/isNumber}}{{/isUuid}}{{/isUri}}

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: When withXml is enabled for an unformatted type: number enum, this condition removes @XmlEnumValue, so JAXB loses the mapping from generated constant names to numeric XML values. Keep the annotation for isNumber and quote its literal value, while retaining the URI/UUID exclusions.

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/okhttp-gson/modelEnum.mustache, line 26:

<comment>When `withXml` is enabled for an unformatted `type: number` enum, this condition removes `@XmlEnumValue`, so JAXB loses the mapping from generated constant names to numeric XML values. Keep the annotation for `isNumber` and quote its literal value, while retaining the URI/UUID exclusions.</comment>

<file context>
@@ -23,7 +23,7 @@ import com.google.gson.stream.JsonWriter;
      {{/enumDescription}}
   {{#withXml}}
-  @XmlEnumValue({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}})
+  {{^isUri}}{{^isUuid}}{{^isNumber}}@XmlEnumValue({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}){{/isNumber}}{{/isUuid}}{{/isUri}}
   {{/withXml}}
   {{{name}}}({{{value}}}){{^-last}},
</file context>
Suggested change
{{^isUri}}{{^isUuid}}{{^isNumber}}@XmlEnumValue({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}){{/isNumber}}{{/isUuid}}{{/isUri}}
{{^isUri}}{{^isUuid}}@XmlEnumValue({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{#isNumber}}"{{/isNumber}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{#isNumber}}"{{/isNumber}}){{/isUuid}}{{/isUri}}

@Override
public void serialize({{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} obj, JsonGenerator generator, SerializationContext ctx) {
generator.write(obj.value{{#isUri}}.toASCIIString(){{/isUri}});
generator.write({{#isFreeFormObject}}String.valueOf(obj.value){{/isFreeFormObject}}{{^isFreeFormObject}}obj.value{{#isUri}}.toASCIIString(){{/isUri}}{{/isFreeFormObject}});

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: When an enum value is a free-form object, this serializer emits the object's Java string representation as a JSON string, losing its object structure. Serialize the value through the JSON-B SerializationContext instead of converting it to String.

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/enumOuterClass.mustache, line 54:

<comment>When an enum value is a free-form object, this serializer emits the object's Java string representation as a JSON string, losing its object structure. Serialize the value through the JSON-B `SerializationContext` instead of converting it to `String`.</comment>

<file context>
@@ -51,7 +51,7 @@ import java.net.URI;
     @Override
     public void serialize({{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} obj, JsonGenerator generator, SerializationContext ctx) {
-      generator.write(obj.value{{#isUri}}.toASCIIString(){{/isUri}});
+      generator.write({{#isFreeFormObject}}String.valueOf(obj.value){{/isFreeFormObject}}{{^isFreeFormObject}}obj.value{{#isUri}}.toASCIIString(){{/isUri}}{{/isFreeFormObject}});
     }
   }
</file context>
Suggested change
generator.write({{#isFreeFormObject}}String.valueOf(obj.value){{/isFreeFormObject}}{{^isFreeFormObject}}obj.value{{#isUri}}.toASCIIString(){{/isUri}}{{/isFreeFormObject}});
{{#isFreeFormObject}}ctx.serialize(obj.value, generator);{{/isFreeFormObject}}{{^isFreeFormObject}}generator.write(obj.value{{#isUri}}.toASCIIString(){{/isUri}});{{/isFreeFormObject}}


{{#allowableValues}}
{{#enumVars}}{{#withXml}}@XmlEnumValue({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}) {{/withXml}}@JsonProperty({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}) {{name}}({{dataType}}.valueOf({{{value}}})){{^-last}},
{{#enumVars}}{{#withXml}}{{^isUri}}{{^isUuid}}{{^isNumber}}@XmlEnumValue({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}){{/isNumber}}{{/isUuid}}{{/isUri}} {{/withXml}}@JsonProperty({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}) {{name}}({{^isUri}}{{^isUuid}}{{^isNumeric}}{{^isFreeFormObject}}{{dataType}}.valueOf({{/isFreeFormObject}}{{/isNumeric}}{{/isUuid}}{{/isUri}}{{{value}}}{{^isUri}}{{^isUuid}}{{^isNumeric}}{{^isFreeFormObject}}){{/isFreeFormObject}}{{/isNumeric}}{{/isUuid}}{{/isUri}}){{^-last}},

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: When withXml is enabled for an unformatted type: number enum, this guard removes every @XmlEnumValue. Because the enum still declares @XmlEnum({{dataType}}.class), JAXB falls back to Java constant names instead of numeric XML values; keep the XML value annotation for numeric enums.

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/JavaJaxRS/cxf-ext/enumClass.mustache, line 8:

<comment>When `withXml` is enabled for an unformatted `type: number` enum, this guard removes every `@XmlEnumValue`. Because the enum still declares `@XmlEnum({{dataType}}.class)`, JAXB falls back to Java constant names instead of numeric XML values; keep the XML value annotation for numeric enums.</comment>

<file context>
@@ -5,7 +5,7 @@
 
     {{#allowableValues}}
-    {{#enumVars}}{{#withXml}}@XmlEnumValue({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}) {{/withXml}}@JsonProperty({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}) {{name}}({{^isUri}}{{^isUuid}}{{^isNumeric}}{{^isFreeFormObject}}{{dataType}}.valueOf({{/isFreeFormObject}}{{/isNumeric}}{{/isUuid}}{{/isUri}}{{{value}}}{{^isUri}}{{^isUuid}}{{^isNumeric}}{{^isFreeFormObject}}){{/isFreeFormObject}}{{/isNumeric}}{{/isUuid}}{{/isUri}}){{^-last}},
+    {{#enumVars}}{{#withXml}}{{^isUri}}{{^isUuid}}{{^isNumber}}@XmlEnumValue({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}){{/isNumber}}{{/isUuid}}{{/isUri}} {{/withXml}}@JsonProperty({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}) {{name}}({{^isUri}}{{^isUuid}}{{^isNumeric}}{{^isFreeFormObject}}{{dataType}}.valueOf({{/isFreeFormObject}}{{/isNumeric}}{{/isUuid}}{{/isUri}}{{{value}}}{{^isUri}}{{^isUuid}}{{^isNumeric}}{{^isFreeFormObject}}){{/isFreeFormObject}}{{/isNumeric}}{{/isUuid}}{{/isUri}}){{^-last}},
     {{/-last}}{{#-last}};{{/-last}}{{/enumVars}}
     {{/allowableValues}}
</file context>

{{/enumDescription}}
{{#withXml}}
@XmlEnumValue({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}})
{{^isUri}}{{^isUuid}}{{^isNumber}}@XmlEnumValue({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}){{/isNumber}}{{/isUuid}}{{/isUri}}

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: For Object-type enums (isFreeFormObject, e.g. type: object with additionalProperties: false), the new guard emits @XmlEnumValue because isNumber/isUri/isUuid are all false. The value is only quoted for integer/double/long/float, so an Object enum produces the unquoted @XmlEnumValue(abc), a compile error in the generated Java when withXml is on. Add {{^isFreeFormObject}} to the guard, matching the isFreeFormObject condition the PR applies to the enumClass templates.

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/okhttp-gson/modelInnerEnum.mustache, line 18:

<comment>For Object-type enums (isFreeFormObject, e.g. type: object with additionalProperties: false), the new guard emits @XmlEnumValue because isNumber/isUri/isUuid are all false. The value is only quoted for integer/double/long/float, so an Object enum produces the unquoted @XmlEnumValue(abc), a compile error in the generated Java when withXml is on. Add {{^isFreeFormObject}} to the guard, matching the isFreeFormObject condition the PR applies to the enumClass templates.</comment>

<file context>
@@ -15,7 +15,7 @@
     {{/enumDescription}}
     {{#withXml}}
-    @XmlEnumValue({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}})
+    {{^isUri}}{{^isUuid}}{{^isNumber}}@XmlEnumValue({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}){{/isNumber}}{{/isUuid}}{{/isUri}}
     {{/withXml}}
     {{{name}}}({{{value}}}){{^-last}},
</file context>

{{/enumDescription}}
{{#withXml}}
@XmlEnumValue({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}})
{{^isUri}}{{^isUuid}}{{^isNumber}}@XmlEnumValue({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}){{/isNumber}}{{/isUuid}}{{/isUri}}

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: When withXml is enabled for number, URI, or UUID enums, this suppresses @XmlEnumValue and makes JAXB use the Java enum constant name instead of the OpenAPI value. Preserve the XML lexical value in a compile-time string, adding raw enum-value metadata if needed, rather than dropping the annotation.

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-micronaut/common/model/modelEnum.mustache, line 24:

<comment>When `withXml` is enabled for number, URI, or UUID enums, this suppresses `@XmlEnumValue` and makes JAXB use the Java enum constant name instead of the OpenAPI value. Preserve the XML lexical value in a compile-time string, adding raw enum-value metadata if needed, rather than dropping the annotation.</comment>

<file context>
@@ -21,7 +21,7 @@ import com.fasterxml.jackson.annotation.JsonValue;
             {{/enumDescription}}
             {{#withXml}}
-    @XmlEnumValue({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}})
+    {{^isUri}}{{^isUuid}}{{^isNumber}}@XmlEnumValue({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}){{/isNumber}}{{/isUuid}}{{/isUri}}
             {{/withXml}}
     {{{name}}}({{{value}}}){{^-last}},{{/-last}}{{#-last}};{{/-last}}
</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] Inner Enum generation with BigDecimal values results in compilation error

1 participant