mbknor / mbknor-jackson-jsonSchema

Generate JSON Schema with Polymorphism using Jackson annotations
MIT License
234 stars 79 forks source link

JsonNullable is generated incorrectly #146

Open Niskaru opened 3 years ago

Niskaru commented 3 years ago

Hi,

I found an issue when I am using org.openapitools.jackson.nullable.JsonNullable. The generator completely ignores the original class.

Here is my case: I have these 3 classes that are auto generated and I can't change

import java.util.List;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import org.openapitools.jackson.nullable.JsonNullable;
import com.fasterxml.jackson.annotation.JsonProperty;

public class ClassOne {

    @JsonProperty("textField")
    private String textField;

    @JsonProperty("list")
    @Valid
    private JsonNullable<List<ClassTwo>> list;

    @JsonProperty("testClass")
    @Valid
    private JsonNullable<ClassThree> testClass;

    @NotNull
    public String getTextField() {
        return textField;
    }

    public void setTextField(String textField) {
        this.textField = textField;
    }

    @Valid
    @Size(min=0)
    public JsonNullable<List<ClassTwo>> getList() {
        return list;
    }

    public void setList(JsonNullable<List<ClassTwo>> list) {
        this.list = list;
    }

    @NotNull
    public JsonNullable<ClassThree> getTestClass() {
        return testClass;
    }

    public void setTestClass(JsonNullable<ClassThree> testClass) {
        this.testClass = testClass;
    }

}
import javax.validation.constraints.NotNull;
import com.fasterxml.jackson.annotation.JsonProperty;

public class ClassTwo {

    @JsonProperty("fieldOne")
    private String fieldOne;

    @JsonProperty("filedTwo")
    private Integer filedTwo;

    public String getFieldOne() {
        return fieldOne;
    }

    public void setFieldOne(String fieldOne) {
        this.fieldOne = fieldOne;
    }

    @NotNull
    public Integer getFiledTwo() {
        return filedTwo;
    }

    public void setFiledTwo(Integer filedTwo) {
        this.filedTwo = filedTwo;
    }

}
import com.fasterxml.jackson.annotation.JsonProperty;

public class ClassThree {

    @JsonProperty("numberField")
    private Integer numberField;

    public Integer getNumberField() {
        return numberField;
    }

    public void setNumberField(Integer numberField) {
        this.numberField = numberField;
    }

}

This is my code:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.kjetland.jackson.jsonSchema.JsonSchemaConfig;
import com.kjetland.jackson.jsonSchema.JsonSchemaGenerator;

@Service
public class MyService {

    private Logger logger = LoggerFactory.getLogger(MyService.class);

    public void generate() throws Exception {

        JsonSchemaConfig config = JsonSchemaConfig.vanillaJsonSchemaDraft4();

        ObjectMapper schemaObjectMapper = new ObjectMapper();

        JsonSchemaGenerator generator = new JsonSchemaGenerator(schemaObjectMapper, config.withFailOnUnknownProperties(false));

        String jsonSchema = schemaObjectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(generator.generateJsonSchema(ClassOne.class));

        logger.debug(jsonSchema);
    }
}

When I run it generates a json schema that looks like this:

{
  "$schema" : "http://json-schema.org/draft-04/schema#",
  "title" : "Class One",
  "type" : "object",
  "additionalProperties" : true,
  "properties" : {
    "textField" : {
      "type" : "string"
    },
    "list" : {
      "$ref" : "#/definitions/JsonNullable(List(ClassTwo))"
    },
    "testClass" : {
      "$ref" : "#/definitions/JsonNullable(ClassThree)"
    }
  },
  "required" : [ "textField", "testClass" ],
  "definitions" : {
    "JsonNullable(List(ClassTwo))" : {
      "type" : "object",
      "additionalProperties" : true,
      "properties" : {
        "present" : {
          "type" : "boolean"
        }
      },
      "required" : [ "present" ]
    },
    "JsonNullable(ClassThree)" : {
      "type" : "object",
      "additionalProperties" : true,
      "properties" : {
        "present" : {
          "type" : "boolean"
        }
      },
      "required" : [ "present" ]
    }
  }
}

As you can see it generated the same schema for both JsonNullable<List> and JsonNullable although these are completely different looking fields and classes. It just generates schema for the JsonNullable and ignores the class within it.

This is my pom.xml:

    <dependency>
            <groupId>com.kjetland</groupId>
            <artifactId>mbknor-jackson-jsonschema_2.12</artifactId>
            <version>1.0.39</version>
    </dependency>

    <dependency>
            <groupId>org.openapitools</groupId>
            <artifactId>jackson-databind-nullable</artifactId>
            <version>0.1.0</version>
    </dependency>

    <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
    </dependency>