Skip to content

[BUG][JAVA][Spring] With NonNull field we can't have an empty constructor #22604

@pkernevez

Description

@pkernevez

Bug Report Checklist

  • Have you provided a full/minimal spec to reproduce the issue?
  • Have you validated the input using an OpenAPI validator?
  • Have you tested with the latest master to confirm the issue still exists?
  • Have you searched for related issues/PRs?
  • What's the actual output vs expected output?
  • [Optional] Sponsorship to speed up the bug fix or feature request (example)
Description

pojo.mustache generate an empty constructor, but this is not valid when having @nonnull fields with JSpecify.

openapi-generator version

7.18.2, this is not a regression

OpenAPI declaration file content or url

My Maven plugin conf:

                    <configuration>
                        <generatorName>spring</generatorName>
                        <configOptions>
                            <additionalModelTypeAnnotations>@org.jspecify.annotations.NullMarked</additionalModelTypeAnnotations>
                        </configOptions>
...
                        <importMappings>
                            <importMapping>Nullable=org.jspecify.annotations.Nullable</importMapping>
                        </importMappings>
                    </configuration>
Generation Details

Except with specific vendor configuration, there is an empty constructor that is always generated.
It should not be generated when another constructor exists for non nullable fields.
It can be summary with: when openApiNullable we should not have an empty constructor, because if another one exists, the empty constructor is not valid. And if we don't have another constructor, we don't need to generate an empty, the default one is enough.

I do a first PR with this approach, but I think it won't be possible for existing framework like object mapper to not have empty constructor.
My PR try to do this, but breaks a lot of code.

Should I change it with a new Java parameter : generateConstructorWithNoArg and a defaut value 'true' ?

Steps to reproduce

Setup JSpecify (like in my pom example) and NullAway.
Run the generator, when compiling the following Warns are generated:

[WARNING] .../target/generated-sources/src/main/java/tech/generated/dto/ChatRequestDto.java:[29,10] [NullAway] initializer method does not guarantee @NonNull field newQuestion (line 25) is initialized along all control-flow paths (remember to check for exceptions or early returns).
    (see http://t.uber.com/nullaway )

Generated code:

/**
 * The context of the conversation and the new question. 
 */
@org.jspecify.annotations.NullMarked

@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2025-12-30T18:59:30.799067+01:00[Europe/Zurich]", comments = "Generator version: 7.18.0")
public class ChatRequestDto {

  private String newQuestion; /* <== Non Nullable without default value */

  private String previousConversation = "";

  public ChatRequestDto() {
    super(); /* <== we are not initializing the field  newQuestion here */
  }

  /**
   * Constructor with only required parameters
   */
  public ChatRequestDto(String newQuestion, String previousConversation) {
    this.newQuestion = newQuestion;
    this.previousConversation = previousConversation;
  }
Related issues/PRs

All related to JSpecify and new Spring support.
#22599
#22603

Suggest a fix

See PR

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions