Skip to content

[BUG][JAVA][Spring] Required child attributes that override optional parent attributes are ignored by validation and required args constructors #22686

@kzander91

Description

@kzander91

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

With REF_AS_PARENT_IN_ALLOF=true, when a child type inherits an optional attribute and overrides it as required, the child type's required args constructor ignores that optional attribute.

For example, the following class is generated for the parent type, with the single required property accepted in the required args constructor:

public class ParentType {

  private @Nullable String optionalProp;

  private String requiredProp;

  public ParentType() {
    super();
  }

  /**
   * Constructor with only required parameters
   */
  public ParentType(String requiredProp) {
    this.requiredProp = requiredProp;
  }

  @Schema(name = "optionalProp", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
  @JsonProperty("optionalProp")
  public @Nullable String getOptionalProp() {
    return optionalProp;
  }

  // ...

  @NotNull 
  @Schema(name = "requiredProp", requiredMode = Schema.RequiredMode.REQUIRED)
  @JsonProperty("requiredProp")
  public String getRequiredProp() {
    return requiredProp;
  }

  // ...
}

When a child type inherits from ParentType and marks the inherited optionalProp as required, the following is generated:

public class ChildType extends ParentType {

  public ChildType() {
    super();
  }

  /**
   * Constructor with only required parameters
   */
  public ChildType(String optionalProp, String requiredProp) { // <-- `optionalProp` is ignored!
    super(requiredProp);
  }

  // ... no overridden getter for `optionalProp` with `@NotNull`
}

Note how the child's constructor accepts but then ignores the optionalProp attribute.
Also, @NotNull should be added to an overridden getter to enforce that the attribute is required in this child type.

One workaround to avoid accidental use of the constructor is to disable the generation of the required args constructor with -p generatedConstructorWithRequiredArgs=false (e.g. by Jackson, which as of Jackson 3 uses that constructor, resulting in optionalProp values from incoming JSON not to be bound).
Apart from refactoring the spec, I haven't found a workaround to have the correct validation annotations to be generated on the child type.

openapi-generator version

7.18.0, 7.19.0-SNAPSHOT

OpenAPI declaration file content or url
openapi: 3.0.3
info:
  title: Title
  version: "1"
paths:
  /test:
    get:
      responses:
        "200":
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ChildType'
components:
  schemas:
    ParentType:
      type: object
      properties:
        optionalProp:
          type: string
        requiredProp:
          type: string
      required:
       - requiredProp
    ChildType:
      allOf:
        - $ref: '#/components/schemas/ParentType'
        - type: object
          required:
            - optionalProp
Generation Details

java -jar openapi-generator-cli-7.19.0-SNAPSHOT.jar generate -g spring -i spec.yaml -o out --openapi-normalizer REF_AS_PARENT_IN_ALLOF=true

Suggest a Fix

The required args constructor of the child should set the affected attribute itself, and the child should override the parent's getter and add @NotNull.

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