Skip to content

[JAVA-SPRING] Fix missing nullable on all args constructor and fluent setters#24263

Open
Exidex wants to merge 1 commit into
OpenAPITools:masterfrom
Exidex:fix-missing-nullable-in-java-spring
Open

[JAVA-SPRING] Fix missing nullable on all args constructor and fluent setters#24263
Exidex wants to merge 1 commit into
OpenAPITools:masterfrom
Exidex:fix-missing-nullable-in-java-spring

Conversation

@Exidex

@Exidex Exidex commented Jul 9, 2026

Copy link
Copy Markdown

PR checklist

  • Read the contribution guidelines.
  • 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 WSL)
    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.
  • If your PR is targeting a particular programming language, @mention the technical committee members, so they are more likely to review the pull request.

JavaSpring:
@cachescrubber (2022/02) @welshm (2022/02) @MelleD (2022/02) @atextor (2022/02) @manedev79 (2022/02) @javisst (2022/02) @borsch (2022/02) @banlevente (2022/02) @Zomzog (2022/09) @martin-mfg (2023/08)

Fixes #23681
Fixes #24109

Supersedes #24114
Supersedes #23688
Both PRs seem to try to fix respective issues but are wrong


Summary by cubic

Fixes missing @Nullable on all-args constructors and fluent setters in JavaSpring models when using JSpecify. Places annotations correctly on qualified types and enums; fixes #23681 and #24109.

  • Bug Fixes
    • Add @Nullable to constructor and fluent setter parameters for nullable fields (including enums).
    • Add nullableDatatypeWithEnum partial using lambda.jSpecifyDatatype and use it in pojo.mustache to insert annotations within qualified types (e.g., org.springframework.core.io.@Nullable Resource); refresh samples.

Written for commit a49d634. Summary will update on new commits.

Review in cubic

@Exidex Exidex force-pushed the fix-missing-nullable-in-java-spring branch from b30d9ae to a49d634 Compare July 9, 2026 10:40
@Exidex Exidex changed the title Fix missing nullable on all args constructor and fluent setters [JAVA-SPRING] Fix missing nullable on all args constructor and fluent setters Jul 9, 2026

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

1 issue found and verified against the latest diff

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:137">
P2: When `useOptional=true`, optional scalar parameters in the all-args constructor and fluent setter still accept null at runtime (they’re wrapped in `Optional.ofNullable`), but the generated parameter signature omits `@Nullable`. The `nullableAnnotation` partial gates `@Nullable` behind `{{^useOptional}}`, and the `jSpecifyDatatype` lambda only marks the type when that annotation is emitted, so neither path compensates. This leaves a null-safety mismatch for callers in null-checked codebases. Consider extending the annotation logic so that optional properties using `Optional.ofNullable` also carry `@Nullable` on their parameters.</violation>
</file>

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

Re-trigger cubic

* Constructor with all args parameters
*/
public {{classname}}({{#vendorExtensions.x-java-all-args-constructor-vars}}{{>nullableAnnotation}}{{{datatypeWithEnum}}} {{name}}{{^-last}}, {{/-last}}{{/vendorExtensions.x-java-all-args-constructor-vars}}) {
public {{classname}}({{#vendorExtensions.x-java-all-args-constructor-vars}}{{>nullableAnnotation}}{{>nullableDatatypeWithEnum}} {{name}}{{^-last}}, {{/-last}}{{/vendorExtensions.x-java-all-args-constructor-vars}}) {

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 useOptional=true, optional scalar parameters in the all-args constructor and fluent setter still accept null at runtime (they’re wrapped in Optional.ofNullable), but the generated parameter signature omits @Nullable. The nullableAnnotation partial gates @Nullable behind {{^useOptional}}, and the jSpecifyDatatype lambda only marks the type when that annotation is emitted, so neither path compensates. This leaves a null-safety mismatch for callers in null-checked codebases. Consider extending the annotation logic so that optional properties using Optional.ofNullable also carry @Nullable on their parameters.

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 137:

<comment>When `useOptional=true`, optional scalar parameters in the all-args constructor and fluent setter still accept null at runtime (they’re wrapped in `Optional.ofNullable`), but the generated parameter signature omits `@Nullable`. The `nullableAnnotation` partial gates `@Nullable` behind `{{^useOptional}}`, and the `jSpecifyDatatype` lambda only marks the type when that annotation is emitted, so neither path compensates. This leaves a null-safety mismatch for callers in null-checked codebases. Consider extending the annotation logic so that optional properties using `Optional.ofNullable` also carry `@Nullable` on their parameters.</comment>

<file context>
@@ -134,7 +134,7 @@ public {{>sealed}}class {{classname}}{{#parent}} extends {{{parent}}}{{/parent}}
    * Constructor with all args parameters
    */
-  public {{classname}}({{#vendorExtensions.x-java-all-args-constructor-vars}}{{>nullableAnnotation}}{{{datatypeWithEnum}}} {{name}}{{^-last}}, {{/-last}}{{/vendorExtensions.x-java-all-args-constructor-vars}}) {
+  public {{classname}}({{#vendorExtensions.x-java-all-args-constructor-vars}}{{>nullableAnnotation}}{{>nullableDatatypeWithEnum}} {{name}}{{^-last}}, {{/-last}}{{/vendorExtensions.x-java-all-args-constructor-vars}}) {
   {{#parent}}
       super({{#parentVars}}{{name}}{{^-last}}, {{/-last}}{{/parentVars}});
</file context>

@Exidex Exidex Jul 9, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

This seems to be a way bigger task than the current change, and is mostly not related to the bug I am fixing here

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

Labels

None yet

Projects

None yet

1 participant