Feature/fix json include#24428
Conversation
There was a problem hiding this comment.
3 issues found across 10 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/JavaSpring/pojo.mustache">
<violation number="1" location="modules/openapi-generator/src/main/resources/JavaSpring/pojo.mustache:66">
P1: A manual `x-jackson-json-include-policy: NONE` now generates an annotation even though `NONE` means no annotation; because `SpringCodegen` also skips the import for this value, generated Java fails to compile. Suppress the template section for `NONE` (or remove that extension before rendering).</violation>
<violation number="2" location="modules/openapi-generator/src/main/resources/JavaSpring/pojo.mustache:66">
P2: Invalid `x-jackson-json-include-policy` values now produce uncompilable Java/Kotlin output because the template inserts the extension directly as a `JsonInclude.Include` constant. Validating the override against the supported policies (or rejecting it during generator processing) would turn this into an actionable generation error instead of a downstream compile failure.</violation>
</file>
<file name="modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinSpringServerCodegen.java">
<violation number="1" location="modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinSpringServerCodegen.java:1356">
P2: With `openApiNullable=true` alone, explicit `null` on optional non-nullable fields now falls through to mapper defaults rather than failing. This changes the documented strict-null contract; retain `Nulls.FAIL` for that mode or make the changed behavior explicit and compatible for existing configurations.</violation>
</file>
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
| @JsonInclude(JsonInclude.Include.NON_ABSENT) | ||
| {{/vendorExtensions.x-is-jackson-optional-nullable}} | ||
| {{#vendorExtensions.x-jackson-json-include-policy}} | ||
| @JsonInclude(JsonInclude.Include.{{{vendorExtensions.x-jackson-json-include-policy}}}) |
There was a problem hiding this comment.
P1: A manual x-jackson-json-include-policy: NONE now generates an annotation even though NONE means no annotation; because SpringCodegen also skips the import for this value, generated Java fails to compile. Suppress the template section for NONE (or remove that extension before rendering).
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/JavaSpring/pojo.mustache, line 66:
<comment>A manual `x-jackson-json-include-policy: NONE` now generates an annotation even though `NONE` means no annotation; because `SpringCodegen` also skips the import for this value, generated Java fails to compile. Suppress the template section for `NONE` (or remove that extension before rendering).</comment>
<file context>
@@ -62,14 +62,9 @@ public {{>sealed}}class {{classname}}{{#parent}} extends {{{parent}}}{{/parent}}
- @JsonInclude(JsonInclude.Include.NON_ABSENT)
- {{/vendorExtensions.x-is-jackson-optional-nullable}}
+ {{#vendorExtensions.x-jackson-json-include-policy}}
+ @JsonInclude(JsonInclude.Include.{{{vendorExtensions.x-jackson-json-include-policy}}})
+ {{/vendorExtensions.x-jackson-json-include-policy}}
{{/jackson}}
</file context>
There was a problem hiding this comment.
This was taken care of
| // Always emit @JsonInclude(NON_NULL) so null fields are omitted from serialized output regardless | ||
| // of who is deserializing on the other end — closer to spec, avoids round-trip failures. | ||
| if (!property.required && !property.isNullable) { | ||
| if (Boolean.TRUE.equals(generateJsonSetterNullsAnnotations) && !property.required && !property.isNullable) { |
There was a problem hiding this comment.
P2: With openApiNullable=true alone, explicit null on optional non-nullable fields now falls through to mapper defaults rather than failing. This changes the documented strict-null contract; retain Nulls.FAIL for that mode or make the changed behavior explicit and compatible for existing configurations.
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/java/org/openapitools/codegen/languages/KotlinSpringServerCodegen.java, line 1356:
<comment>With `openApiNullable=true` alone, explicit `null` on optional non-nullable fields now falls through to mapper defaults rather than failing. This changes the documented strict-null contract; retain `Nulls.FAIL` for that mode or make the changed behavior explicit and compatible for existing configurations.</comment>
<file context>
@@ -1280,20 +1349,18 @@ public void postProcessModelProperty(CodegenModel model, CodegenProperty propert
- // Always emit @JsonInclude(NON_NULL) so null fields are omitted from serialized output regardless
- // of who is deserializing on the other end — closer to spec, avoids round-trip failures.
- if (!property.required && !property.isNullable) {
+ if (Boolean.TRUE.equals(generateJsonSetterNullsAnnotations) && !property.required && !property.isNullable) {
if (openApiNullable) {
property.vendorExtensions.put("x-has-json-setter-nulls-fail", true);
</file context>
| if (Boolean.TRUE.equals(generateJsonSetterNullsAnnotations) && !property.required && !property.isNullable) { | |
| if ((Boolean.TRUE.equals(generateJsonSetterNullsAnnotations) || openApiNullable) && !property.required && !property.isNullable) { |
| @JsonInclude(JsonInclude.Include.NON_ABSENT) | ||
| {{/vendorExtensions.x-is-jackson-optional-nullable}} | ||
| {{#vendorExtensions.x-jackson-json-include-policy}} | ||
| @JsonInclude(JsonInclude.Include.{{{vendorExtensions.x-jackson-json-include-policy}}}) |
There was a problem hiding this comment.
P2: Invalid x-jackson-json-include-policy values now produce uncompilable Java/Kotlin output because the template inserts the extension directly as a JsonInclude.Include constant. Validating the override against the supported policies (or rejecting it during generator processing) would turn this into an actionable generation error instead of a downstream compile failure.
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/JavaSpring/pojo.mustache, line 66:
<comment>Invalid `x-jackson-json-include-policy` values now produce uncompilable Java/Kotlin output because the template inserts the extension directly as a `JsonInclude.Include` constant. Validating the override against the supported policies (or rejecting it during generator processing) would turn this into an actionable generation error instead of a downstream compile failure.</comment>
<file context>
@@ -62,14 +62,9 @@ public {{>sealed}}class {{classname}}{{#parent}} extends {{{parent}}}{{/parent}}
- @JsonInclude(JsonInclude.Include.NON_ABSENT)
- {{/vendorExtensions.x-is-jackson-optional-nullable}}
+ {{#vendorExtensions.x-jackson-json-include-policy}}
+ @JsonInclude(JsonInclude.Include.{{{vendorExtensions.x-jackson-json-include-policy}}})
+ {{/vendorExtensions.x-jackson-json-include-policy}}
{{/jackson}}
</file context>
There was a problem hiding this comment.
This was taken care of
There was a problem hiding this comment.
1 issue found across 10 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/test/java/org/openapitools/codegen/kotlin/spring/KotlinSpringServerCodegenTest.java">
<violation number="1" location="modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/spring/KotlinSpringServerCodegenTest.java:6910">
P2: The new invalid-override regression test cannot run because its referenced fixture `issue_24401_json_include_invalid_override.yaml` is not present in the repository. Adding the fixture (with `NOT_A_REAL_POLICY`) or removing the test reference is needed; otherwise the Kotlin Spring test suite fails unconditionally.</violation>
</file>
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
| @Test(description = "Issue #24401 – invalid manual override fails fast (kotlin-spring)") | ||
| public void jsonInclude_manualOverride_invalid_failsWithActionableError() { | ||
| Throwable thrown = Assert.expectThrows(Throwable.class, () -> generateFromContract( | ||
| "src/test/resources/3_0/spring/issue_24401_json_include_invalid_override.yaml", |
There was a problem hiding this comment.
P2: The new invalid-override regression test cannot run because its referenced fixture issue_24401_json_include_invalid_override.yaml is not present in the repository. Adding the fixture (with NOT_A_REAL_POLICY) or removing the test reference is needed; otherwise the Kotlin Spring test suite fails unconditionally.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/spring/KotlinSpringServerCodegenTest.java, line 6910:
<comment>The new invalid-override regression test cannot run because its referenced fixture `issue_24401_json_include_invalid_override.yaml` is not present in the repository. Adding the fixture (with `NOT_A_REAL_POLICY`) or removing the test reference is needed; otherwise the Kotlin Spring test suite fails unconditionally.</comment>
<file context>
@@ -6690,28 +6695,226 @@ public void requiredNullable_scenario3_optionalNonNullable_withJackson3() throws
+ @Test(description = "Issue #24401 – invalid manual override fails fast (kotlin-spring)")
+ public void jsonInclude_manualOverride_invalid_failsWithActionableError() {
+ Throwable thrown = Assert.expectThrows(Throwable.class, () -> generateFromContract(
+ "src/test/resources/3_0/spring/issue_24401_json_include_invalid_override.yaml",
+ Map.of(KotlinSpringServerCodegen.GENERATE_JSON_INCLUDE_ANNOTATIONS, "true")));
+
</file context>
There was a problem hiding this comment.
This was taken care of
…rExtension and CodegenConstants
…ON include policy handling
There was a problem hiding this comment.
1 issue found across 14 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/java/org/openapitools/codegen/languages/SpringCodegen.java">
<violation number="1" location="modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java:1277">
P2: Models using Lombok-generated setters ignore `generateJsonSetterNullsAnnotations=true`, so explicit JSON nulls can still overwrite optional non-nullable defaults. Render the `@JsonSetter` annotation on the field or otherwise support the Lombok setter path.</violation>
</file>
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
| // setter so an explicit null in the payload does not overwrite the field's default. Only emitted when | ||
| // generateJsonSetterNullsAnnotations is explicitly enabled; otherwise deserialization defers to the mapper. | ||
| if (Boolean.TRUE.equals(generateJsonSetterNullsAnnotations) && !property.required && !property.isNullable && !openApiNullable) { | ||
| property.vendorExtensions.put("x-has-json-setter-nulls-skip", true); |
There was a problem hiding this comment.
P2: Models using Lombok-generated setters ignore generateJsonSetterNullsAnnotations=true, so explicit JSON nulls can still overwrite optional non-nullable defaults. Render the @JsonSetter annotation on the field or otherwise support the Lombok setter path.
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/java/org/openapitools/codegen/languages/SpringCodegen.java, line 1277:
<comment>Models using Lombok-generated setters ignore `generateJsonSetterNullsAnnotations=true`, so explicit JSON nulls can still overwrite optional non-nullable defaults. Render the `@JsonSetter` annotation on the field or otherwise support the Lombok setter path.</comment>
<file context>
@@ -1213,24 +1270,48 @@ public void postProcessModelProperty(CodegenModel model, CodegenProperty propert
+ // setter so an explicit null in the payload does not overwrite the field's default. Only emitted when
+ // generateJsonSetterNullsAnnotations is explicitly enabled; otherwise deserialization defers to the mapper.
+ if (Boolean.TRUE.equals(generateJsonSetterNullsAnnotations) && !property.required && !property.isNullable && !openApiNullable) {
+ property.vendorExtensions.put("x-has-json-setter-nulls-skip", true);
+ model.imports.add("JsonSetter");
+ model.imports.add("Nulls");
</file context>
There was a problem hiding this comment.
@cubic-dev-ai, I think I took care of this issue. Please re-review
There was a problem hiding this comment.
@Picazsoo I have started the AI code review. It will take a few minutes to complete.
…th Lombok setters
PR checklist
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.
Summary by cubic
Make
@JsonIncludeand@JsonSetter(nulls=...)emission inspringandkotlin-springopt-in and configurable, restoring 7.23.0-style output by default to avoid unexpected wire contract changes. Also emit@JsonSetter(nulls=...)on fields so it works when Lombok generates setters.New Features
generateJsonIncludeAnnotations(opt-in) to control policy@JsonIncludeon model properties; when unset, emit none and log a warning.generateJsonSetterNullsAnnotations(opt-in) for@JsonSetter(nulls = ...)on optional non‑nullable props; when unset, emit none and log a warning. Annotation is now placed on fields to work with Lombok@Setter.optionalNonNullPropertyJsonIncludewithNON_NULL(default),NON_EMPTY,NON_DEFAULT, orNONE.x-jackson-json-include-policy(always wins); validate against JacksonIncludevalues, accept trimmedNONEto emit nothing, and add imports only when an annotation is emitted.@JsonInclude(NON_ABSENT)forJsonNullable<T>fields.Refactors
JsonIncludePolicyUtils; useCodegenConstantsandVendorExtension.X_JACKSON_JSON_INCLUDE_POLICYacross generators and templates.Written for commit 3dbcd99. Summary will update on new commits.