jackson-module-jsonSchema
jackson-module-jsonSchema copied to clipboard
Generated JSON Schema incorrect for @JsonIdentityReference(alwaysAsId = true)
Hi,
I am trying to create a JSON representation of a datamodel and want to use a JSON Schema to validate the contents. When using the JSON Schema generated by the jsonSchema module I run into trouble when I have a property which is an identify reference (@JsonIdentityReference(alwaysAsId = true)).
For example when we have three classes: ManagingObject (which manages everything), ReferencedObject (the object which is managed by ManagingObject) and ReferencingObject (an object which references to ReferencedObject and is also managed by ManagingObject):
public class ManagingObject {
@JsonManagedReference
public Vector<ReferencedObject> referencedObjects;
@JsonManagedReference
public ReferencingObject referencingObject;
public ManagingObject() {
referencedObjects = new Vector<ReferencedObject>();
}
}
@JsonIdentityInfo(property="id", generator=ObjectIdGenerators.PropertyGenerator.class)
public class ReferencedObject {
public UUID id;
public String someOtherProperty;
public ReferencedObject() {
id = UUID.randomUUID();
}
}
public class ReferencingObject {
@JsonIdentityReference(alwaysAsId = true)
public ReferencedObject referencedObject;
}
When I then create a sample JSON using the following code:
// Create an example JSON.
ObjectMapper objectMapper = new ObjectMapper();
ManagingObject mo = new ManagingObject();
// Create the ReferencedObject and add it to the ManagingObject collection.
ReferencedObject ro = new ReferencedObject();
ro.someOtherProperty = "Something";
mo.referencedObjects.add(ro);
// Create the ReferencingObject and set its referencedObject and also add a reference in the ManagingObject to it.
ReferencingObject rco = new ReferencingObject();
rco.referencedObject = ro;
mo.referencingObject = rco;
// Create a JSON representation of the ManagingObject.
System.out.println(objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(mo));
Then the output is what I would expect (in the ReferencingObject it points directly to the id and doesn't include the full referencedObject):
{
"referencedObjects" : [ {
"id" : "de0fb81e-014d-480a-8b65-01ce2daf719f",
"someOtherProperty" : "Something"
} ],
"referencingObject" : {
"referencedObject" : "de0fb81e-014d-480a-8b65-01ce2daf719f"
}
}
But when I then generate a JSON Schema using the following code:
// Create the JSON Schema.
ObjectMapper objectMapper = new ObjectMapper();
JsonSchemaGenerator jsonSchemaGenerator = new JsonSchemaGenerator(objectMapper);
JsonNode jsonSchema = jsonSchemaGenerator.generateJsonSchema(ManagingObject.class);
System.out.println(objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(jsonSchema));
Then the output is not what I would expect for the referencedObject in ReferencingObject (unless I misunderstand):
{
"$schema" : "http://json-schema.org/draft-04/schema#",
"title" : "Managing Object",
"type" : "object",
"additionalProperties" : false,
"properties" : {
"referencedObjects" : {
"type" : "array",
"items" : {
"$ref" : "#/definitions/ReferencedObject"
}
},
"referencingObject" : {
"$ref" : "#/definitions/ReferencingObject"
}
},
"definitions" : {
"ReferencedObject" : {
"type" : "object",
"additionalProperties" : false,
"properties" : {
"id" : {
"type" : "string"
},
"someOtherProperty" : {
"type" : "string"
}
}
},
"ReferencingObject" : {
"type" : "object",
"additionalProperties" : false,
"properties" : {
"referencedObject" : {
"$ref" : "#/definitions/ReferencedObject"
}
}
}
}
}
When I look at the ReferencingObject definition of the schema I see a JSON Pointer to the ReferencedObject definition for the 'referencedObject' property, but in the example JSON the id is directly mapped (not a full JSON representation of the ReferencedObject). So the JSON produced is not valid according the JSON Schema on the same object model.
Am I doing something wrong or weird here? Or should the JSON Schema look a bit different for the properties which are marked with the annotation @JsonIdentityReference(alwaysAsId = true) ?