DEV Community

Maurício Arcanjo
Maurício Arcanjo

Posted on

How to solve stackoverflow serialization loop with Jackson's annotations @JsonBackReference and @JsonManagedReference

This week, I was refactoring code for an Animal Shelter and encountered a StackOverflow error related to JSON serialization when testing the API. The issue was caused by a bidirectional relationship between the Pet and Abrigo classes. Specifically, the Pet class contains an Abrigo attribute, and the Abrigo class holds a list of Pet objects, as shown in the code below:

public class Pet {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Enumerated(EnumType.STRING)
    private TipoPet tipo;

    private String nome;
    private String raca;
    private Integer idade;
    private String cor;
    private Float peso;
    private Boolean adotado;

    @ManyToOne
    private Abrigo abrigo;

    @OneToOne(mappedBy = "pet")
    private Adocao adocao;
}
Enter fullscreen mode Exit fullscreen mode
public class Abrigo {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String nome;
    private String telefone;
    private String email;

    @OneToMany(mappedBy = "abrigo", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private List<Pet> pets;
}
Enter fullscreen mode Exit fullscreen mode

There are several ways to handle this serialization issue. One recommended approach is to create a DTO (Data Transfer Object) class to control which attributes are returned by the API. Another solution is to use Jackson annotations, such as @JsonBackReference and @JsonManagedReference, to manage JSON serialization and deserialization effectively.

I opted to use them both, and the entities classes were modified as follows:

public class Pet {
    ...
    @JsonBackReference
    @ManyToOne
    private Abrigo abrigo;
    ...
}
Enter fullscreen mode Exit fullscreen mode
public class Abrigo {
    ...
    @OneToMany(mappedBy = "abrigo", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JsonManagedReference
    private List<Pet> pets;
}
Enter fullscreen mode Exit fullscreen mode
  • @JsonManagedReference: Marks the forward part of the reference. Jackson will include the pets list when serializing an Abrigo object.
  • @JsonBackReference: Marks the back part of the reference. Jackson will ignore the abrigo attribute when serializing a Pet object.

By applying these best practices, the serialization loop that causes the StackOverflow error is resolved for this bidirectional relationship, allowing the API to function efficiently.

Top comments (0)