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.

Image of Datadog

The Future of AI, LLMs, and Observability on Google Cloud

Datadog sat down with Google’s Director of AI to discuss the current and future states of AI, ML, and LLMs on Google Cloud. Discover 7 key insights for technical leaders, covering everything from upskilling teams to observability best practices

Learn More

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more