Reputation: 67
I have the pojo DTNodo
, which has a recursive property List<DTNodo>
.
When I try to generate the json schema using jackson I get a java.lang.StackOverflowError
exception.
If I remove the List property it works fine, so the problem is with the recursion.
Is there a way to tell the ObjectMapper of this recursion so it handles it properly? Is there any other way of generating this json schema?
The DTNodo class
public class DTNodo implements Serializable {
private static final long serialVersionUID = 1L;
private Integer idNodo;
private String codigo;
private String descripcion;
private String detalle;
private Integer orden;
private List<DTNodo> hijos;
public Integer getIdNodo() {
return idNodo;
}
public void setIdNodo(Integer idNodo) {
this.idNodo = idNodo;
}
public String getCodigo() {
return codigo;
}
public void setCodigo(String codigo) {
this.codigo = codigo;
}
public String getDescripcion() {
return descripcion;
}
public void setDescripcion(String descripcion) {
this.descripcion = descripcion;
}
public String getDetalle() {
return detalle;
}
public void setDetalle(String detalle) {
this.detalle = detalle;
}
public Integer getOrden() {
return orden;
}
public void setOrden(Integer orden) {
this.orden = orden;
}
public List<DTNodo> getHijos() {
return hijos;
}
public void setHijos(List<DTNodo> hijos) {
this.hijos = hijos;
}
}
The code I used to generate the jsonschema
public static String getJsonSchema(Class<?> clazz) {
ObjectMapper mapper = new ObjectMapper();
JsonSchema schema;
try {
schema = mapper.generateJsonSchema(clazz);
return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(schema);
} catch (IOException e) {
return "Error al generar JsonSchema: " + e.getMessage();
}
}
Upvotes: 3
Views: 2885
Reputation: 850
There is no easy way out. You should try to avoid serializing the properties causing the reference loop in the POJO in one go.
You can achieve something like the following example (objects serialized as references) but you have to make sure the client application is able to deserialize it:
{
"id": "1",
"name": "John",
"friends": [
{
"id": "2",
"name": "Jared",
"friends": [
{
"$ref": "1"
}
]
}
}
What I would do is to serialize the parent object without the attributes causing the loop (@JsonIgnore
). Then serialize the rest and make the client app recompose the object.
You can use @JsonManagedReference
, @JsonBackReference
.
More info: http://www.baeldung.com/jackson-bidirectional-relationships-and-infinite-recursion
Upvotes: 1
Reputation: 8909
ObjectMapper.generateJsonSchema is deprecated. You'll want to use the new JSON schema module instead.
Add com.fasterxml.jackson.module:jackson-module-jsonSchema:${jacksonVersion}
to your project and generate the schema like this:
ObjectMapper mapper = new ObjectMapper();
JsonSchemaGenerator schemaGen = new JsonSchemaGenerator(mapper);
JsonSchema schema = schemaGen.generateSchema(clazz);
mapper.writerWithDefaultPrettyPrinter().writeValueAsString(schema);
Make sure to import the modern JsonSchema from the correct package:
import com.fasterxml.jackson.module.jsonSchema.JsonSchema;
Upvotes: 2