Skip to content

[Bug]: @Nullable annotation incorrectly affects object and sets the type to null #5115

@Mattias-Sehlstedt

Description

@Mattias-Sehlstedt

Description of the problem/issue

PR #5018 introduced support for resolving a @Nullable annotation and having it set the nullability in the respective OAS representation (nullable: true or type: null).

The implementation currently does not handle object-fields correctly, since the nullable is forwarded and retain for schemas that are later used as ref. See #5077 for additional details. An example is

public static class ModelWithObject {

    @Nullable
    private Model nullableModel;

    private Model model;

    @Nullable
    public Model getNullableModel() {
        return nullableModel;
    }

    public void setNullableModel(@Nullable Model model) {
        this.nullableModel = model;
    }

    public Model getModel() {
        return model;
    }

    public void setModel(Model model) {
        this.model = model;
    }
}

public static class Model {

    private NestedModel nestedModel;

    @Nullable
    private NestedModel nullableNestedModel;

    @Nullable
    private NestedModel2 nullableNestedModel2;

    private NestedModel2 nestedModel2;

    public NestedModel getNestedModel() {
        return nestedModel;
    }

    public void setNestedModel(NestedModel nestedModel) {
        this.nestedModel = nestedModel;
    }

    @Nullable
    public NestedModel getNullableNestedModel() {
        return nullableNestedModel;
    }

    public void setNullableNestedModel(@Nullable NestedModel nullableNestedModel) {
        this.nullableNestedModel = nullableNestedModel;
    }

    @Nullable
    public NestedModel2 getNullableNestedModel2() {
        return nullableNestedModel2;
    }

    public void setNullableNestedModel2(@Nullable NestedModel2 nullableNestedModel2) {
        this.nullableNestedModel2 = nullableNestedModel2;
    }

    public NestedModel2 getNestedModel2() {
        return nestedModel2;
    }

    public void setNestedModel2(NestedModel2 nestedModel2) {
        this.nestedModel2 = nestedModel2;
    }
}

public static class NestedModel {
    private String field;

    public String getField() {
        return field;
    }

    public void setField(String field) {
        this.field = field;
    }
}

public static class NestedModel2 {
    private String field2;

    public String getField2() {
        return field2;
    }

    public void setField2(String field2) {
        this.field2 = field2;
    }
}

and it being resolved to:

{
  "schema" : {
    "type" : "object",
    "properties" : {
      "nullableModel" : {
        "$ref" : "#/components/schemas/Model"
      },
      "model" : {
        "$ref" : "#/components/schemas/Model"
      }
    }
  },
  "referencedSchemas" : {
    "Model" : {
      "type" : "object",
      "properties" : {
        "nestedModel" : {
          "$ref" : "#/components/schemas/NestedModel"
        },
        "nullableNestedModel" : {
          "$ref" : "#/components/schemas/NestedModel"
        },
        "nullableNestedModel2" : {
          "$ref" : "#/components/schemas/NestedModel2"
        },
        "nestedModel2" : {
          "$ref" : "#/components/schemas/NestedModel2"
        }
      }
    },
    "ModelWithObject" : {
      "type" : "object",
      "properties" : {
        "nullableModel" : {
          "$ref" : "#/components/schemas/Model"
        },
        "model" : {
          "$ref" : "#/components/schemas/Model"
        }
      }
    },
    "NestedModel" : {
      "type" : "null",      <-- This should not be null
      "properties" : {
        "field" : {
          "type" : "string"
        }
      }
    },
    "NestedModel2" : {
      "type" : "object",
      "properties" : {
        "field2" : {
          "type" : "string"
        }
      }
    }
  }
}

Affected Version

2.2.26

Earliest version the bug appears in (if known):
2.2.24

Steps to Reproduce

Resolve the class provided above and see that it resolves to a schema with type: null for OAS 3.1.

Expected Behavior

The null is not kept for objects and null does not override/replace object.

Actual Behavior

The null might leak depending on what order that fields (models) are read.

Logs / Stack Traces

Additional Context

Checklist

  • I have searched the existing issues and this is not a duplicate.
  • I have provided sufficient information for maintainers to reproduce the issue.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions