I have a spring boot application with frontend and backend connected using apache HttpClient.
There are many bi-directional associations between the entities. For example:
@NamedEntityGraphs(
{
@NamedEntityGraph(name = "graph.ApplicationUserProcesses",
attributeNodes ={
@NamedAttributeNode(value = "processes", subgraph = "processes"),
@NamedAttributeNode(value = "roles")
},
subgraphs = @NamedSubgraph(name = "processes",
attributeNodes = {
@NamedAttributeNode("applicationUsers")
})
)
}
)
public class ApplicationUser implements Serializable {
@Id
private UUID id;
@ManyToMany(cascade = CascadeType.MERGE, fetch = FetchType.LAZY)
@JoinTable( name = "app_user_role",
joinColumns = @JoinColumn(name = "app_user_id"),
inverseJoinColumns = @JoinColumn(name = "app_user_role_id"))
private Set<Role> roles = new HashSet<>();
@JsonIgnore
@ManyToMany(mappedBy = "applicationUsers", fetch = FetchType.LAZY)
private Set<Process> processes = new HashSet<>();
}
public class Process implements Serializable {
@Id
private UUID id;
@ManyToMany( fetch = FetchType.LAZY)
@JoinTable( name = "membership",
joinColumns = @JoinColumn(name = "process_id"),
inverseJoinColumns = @JoinColumn(name = "user_id"))
private Set<ApplicationUser> applicationUsers = new HashSet<>();
}
The process and applicationUser entities have bi-directional association as shown above. The issue is that when the backend returns applicationUser object, there is continuous nesting of objects in the json (as shown below) which is not needed. How to make the json API from the backend stop nesting.
applicationUser:{
processes:[{
process1:{
applicationUser:{
processes:[{
process1:{
}
}]
}
}
}]
}
Is there anyway to prevent the nesting of objects in the json and maintain clean API.
2
Answers
You need to use Jackson’s
@JsonManagedReference
and@JsonBackReference
annotation to avoid that.On parent class where you want to allow child to be included in JSON add
@JsonManagedReference
annotation.On child class where you don’t want to include parent in JSON add
@JsonBackReference
.You should not expose the entity to API instead use DTO/VO which are POJO classes that holds the values. Try Using different POJO classes based on how you want to expose your entity relationship. Or try to avoid bidirectional relationship in entity as generally not required as you will always get child from parent or vice versa.
To prevent nesting of JSON objects in your API, consider using the @JsonBackReference and @JsonManagedReference annotations to manage bi-directional relationships, implement Data Transfer Objects (DTOs) to explicitly control the serialized structure, or utilize Jackson’s customized serialization views to selectively serialize properties based on the context. These approaches allow you to break infinite recursion and tailor the JSON output to meet your API’s requirements.