Skip to content

"minimum": 0.0 is not set when @Min(0) is used #83

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
matlach opened this issue Sep 24, 2015 · 9 comments
Open

"minimum": 0.0 is not set when @Min(0) is used #83

matlach opened this issue Sep 24, 2015 · 9 comments

Comments

@matlach
Copy link

matlach commented Sep 24, 2015

Consider the following:

public class Person {
    @Min(0)
    private int id;
}

when serialized to json schema, will output:

{
  "type" : "object",
  "id" : "urn:jsonschema:xxx:Person",
  "properties" : {
    "id" : {
      "type" : "integer"
    }
}

instead of:

{
  "type" : "object",
  "id" : "urn:jsonschema:xxx:Person",
  "properties" : {
    "id" : {
      "type" : "integer",
      "minimum" : 0.0
    }
}

everything works fine if we define any other number than 0.

By looking at the ValidationConstraintResolver/AnnotationConstraintResolver, why the minimumValue/maximumValue is always converted to double?

When the type is integer, shoudn't the minimum/maximum value stays to an integer format?
When I look at the following documentation:
http://spacetelescope.github.io/understanding-json-schema/reference/numeric.html
Under range, the integer format is preserved. Should I open different issues for this?

Thank you very much!

@alaingiller
Copy link

The problem is in this class:
com.fasterxml.jackson.databind.ser.std.NumberSerializers#DoubleSerializer
If the value is 0 (or 0.0 because is converted to double) then it will be skipped.
This is call there
com.fasterxml.jackson.databind.ser.impl.UnwrappingBeanPropertyWriter#serializeAsField

 if (_suppressableValue != null) {
            if (MARKER_FOR_EMPTY == _suppressableValue) {
                if (ser.isEmpty(prov, value)) {
                    return;
                }
            } else if (_suppressableValue.equals(value)) {
                return;
            }
        }

I try to use config and annotation JsonInclude.Include.ALWAYS but without any success.

final ObjectMapper mapper = new ObjectMapper();
mapper.acceptJsonFormatVisitor(dtoClass, entityVisitor);
mapper.setSerializationInclusion(JsonInclude.Include.ALWAYS).writerWithDefaultPrettyPrinter().writeValueAsString(jsonSchema);

@cowtowncoder
Copy link
Member

@alaingiller Global setting is only default, per-property annotation will override it.

Which Jackson version are you using? Jackson 2.6 did consider default primitive values as "empty", but due to user feedback this change was reverted so that all other versions (and both 2.5 and 2.7) only consider "empty" to apply to container types, Optionals and String.

@alaingiller
Copy link

I'm using jackson-jsonSchema 2.7.3 and also try with 2.7.4 and jackson-databind 2.6.6
The problem is for JSR-303 annotation one should not check if value is "empty". With current implementation @Min(0) cannot work. I also try with @JsonInclude(JsonInclude.Include.ALWAYS) on both class and field but without any success.
For json-schema one shouldn't call isEmpty() of com.fasterxml.jackson.databind.ser.std.NumberSerializers#DoubleSerializer

@cowtowncoder
Copy link
Member

@alaingiller Inclusion is not used for JSR-303 annotation at all. It is only checked when serializing values of POJOs. So for the inclusion settings to take effect here, specific Schema value class has to have inclusion settings that do that. JSON Schema value objects are nothing special from Jackson perspective (nor should they be): they are handled just like any other Java class, based on settings and annotations.

At this point I do not know how to reproduce the problem.

@alaingiller
Copy link

alaingiller commented Jun 16, 2016

Very easy to reproduce:
Create this pojo:

public class SimplePojo{
    @Min(0)
    private int dontWork;

    @Min(1)
    private int workWell;
/* getter & setter */
}

and then:
final SchemaFactoryWrapper entityVisitor = schemaFactoryWrapperClass.newInstance(); final ObjectMapper mapper = new ObjectMapper(); mapper.acceptJsonFormatVisitor(dtoClass, entityVisitor); final JsonSchema jsonSchema = entityVisitor.finalSchema(); System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(jsonSchema));

The generated JsonSchema will be correct for workWell but not for dontWork

@cowtowncoder
Copy link
Member

Correct in... ?

@alaingiller
Copy link

alaingiller commented Jun 16, 2016

Generated json-schema:

{
  "type" : "object",
  "id" : "urn:jsonschema:SimplePojo",
  "properties" : {
    "dontWork" : {
      "type" : "integer"
    },
    "workWell" : {
      "type" : "integer",
      "minimum" : 1.0
    }
}

Correct in case property "dontWork" has "minimum": 0.0 but only "workWell" has it.

@ivan-osipov
Copy link

@alaingiller
You can have problem with "java object -> json" writer. I debug it and check that at runtime JsonSchema object has "minimum" property with value 0.0. And if you will write test and check, then you make sure that everything is ok.

@alaingiller
Copy link

@ivan-osipov : So you say that you run my little exemple and you didn't get the same result as me?
With the current version, @min(0) on an Integer has not the same effect (skipped by the schema-generation) as @min(1) and it's definitely a BUG

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants