我有一个 Spring Boot 应用程序,前端和后端使用 apache HttpClient 连接。 实体之间存在许多双向关联。例如:
@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<>();
}
进程和applicationUser实体具有双向关联,如上所示。问题是,当后端返回applicationUser对象时,json中存在连续的对象嵌套(如下所示),这是不需要的。如何让后端的json API停止嵌套。
applicationUser:{
processes:[{
process1:{
applicationUser:{
processes:[{
process1:{
}
}]
}
}
}]
}
是否有办法防止 json 中对象的嵌套并保持干净的 API。
您需要使用 Jackson 的
@JsonManagedReference
和 @JsonBackReference
注释来避免这种情况。
在您希望允许子级包含在 JSON 中的父类上添加
@JsonManagedReference
注释。
public class ApplicationUser implements Serializable {
@Id
private UUID id;
@JsonManagedReference
@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<>();
@JsonManagedReference
@ManyToMany(mappedBy = "applicationUsers", fetch = FetchType.LAZY)
private Set<Process> processes = new HashSet<>();
}
在您不想在 JSON 中包含父级的子类上添加
@JsonBackReference
。
public class Process implements Serializable {
@Id
private UUID id;
@JsonBackReference
@ManyToMany( fetch = FetchType.LAZY)
@JoinTable( name = "membership",
joinColumns = @JoinColumn(name = "process_id"),
inverseJoinColumns = @JoinColumn(name = "user_id"))
private Set<ApplicationUser> applicationUsers = new HashSet<>();
}
您不应将实体暴露给 API,而应使用 DTO/VO,它们是保存值的 POJO 类。根据您想要如何公开实体关系,尝试使用不同的 POJO 类。或者尝试避免实体中的双向关系,因为通常不需要,因为您总是从父级获得子级,反之亦然。