java – Jackson – Circular Dependency Object Conversion

Question:

Given the classes below, we need to solve the infinite recursion (cyclic dependency) problem and, for that, we use the @JsonIdentityInfo, from Jackson 2+:

@JsonIdentityInfo(scope=Parent.class, generator=ObjectIdGenerators.PropertyGenerator.class, property="id")
@Getter
@Setter
public class Parent {

    private Long id;

    private String nome;

    private List<Child> filhos;

}

@JsonIdentityInfo(scope=Child.class, generator=ObjectIdGenerators.PropertyGenerator.class, property="id")
@Getter
@Setter
@AllArgsConstructor
public class Child {

    private Long id;

    private Parent pai;

    private String nome;
}

We are having problems converting the above entities to JSON. In fact, the conversion of objects of type Parent happens as expected…

{  
   "id":1,
   "nome":"PAI1",
   "filhos":[  
      {  
         "id":10,
         "pai":1,
         "nome":"FILHO1"
      },
      {  
         "id":11,
         "pai":1,
         "nome":"FILHO2"
      }
   ]
}

… however, the same does not happen when trying to convert objects of type Child individually or in lists …

individual:

{
   "id":10,
   "pai":{
      "id":1,
      "nome":"PAI1",
      "filhos":[
         10,
         {
            "id":11,
            "pai":1,
            "nome":"FILHO2"
         }
      ]
   },
   "nome":"FILHO1"
}

ready:

[
   {
      "id":10,
      "pai":{
         "id":1,
         "nome":"PAI1",
         "filhos":[
            10,
            {
               "id":11,
               "pai":1,
               "nome":"FILHO2"
            }
         ]
      },
      "nome":"FILHO1"
   },
   11
]

… we expected that the individual would have the children attribute as null and that the list would also have them as null, in addition to returning only objects, and not object/id, as it happened…

expected individual result:

{
   "id":10,
   "pai":{
      "id":1,
      "nome":"PAI1",
      "filhos":null (ou [])
   },
   "nome":"FILHO1"
}

expected list result: list:

[
   {
      "id":10,
      "pai":{
         "id":1,
         "nome":"PAI1",
         "filhos":null (ou [])
      },
      "nome":"FILHO1"
   },
   {
      "id":11,
      "pai":{
         "id":1,
         "nome":"PAI1",
         "filhos":null (ou [])
      },
      "nome":"FILHO2"
   }   
]

Below is the executed method that returns the above result:

public static void main(String[] args) throws IOException {
    Parent pai = new Parent();
    pai.setId(1L);
    pai.setNome("PAI1");

    List<Child> filhos = new ArrayList<Child>();
    filhos.add(new Child(10L, pai, "FILHO1"));
    filhos.add(new Child(11L, pai, "FILHO2"));

    pai.setFilhos(filhos);

    System.out.println(new ObjectMapper().writeValueAsString(pai));
    System.out.println(new ObjectMapper().writeValueAsString(filhos));
    System.out.println(new ObjectMapper().writeValueAsString(filhos.get(0)));
}

Answer:

We solved it using another approach: instead of using @JsonIdentityInfo, I'm using @JsonView, with Spring version 4.1+ and Jackson 2.5+. For more details, see the following tutorial: https://spring.io/blog/2014/12/02/latest-jackson-integration-improvements-in-spring

Scroll to Top