java - 如何将@JsonManagedReference 和@JsonBackReference 用于与最佳实践的多对多关系?
问题描述
我将非常感谢您解释我的问题。
我有 2 个实体和 1 个桥表实体,
假设他们是团队、用户和团队用户。
团队实体:
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "TEAM_ID")
private Integer id;
@JsonManagedReference
@OneToMany(mappedBy = "team", cascade = CascadeType.ALL, orphanRemoval = true)
private Set<TeamUsers> team_users = new HashSet<>();
用户实体:
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@JsonBackReference
@OneToMany(mappedBy = "user")
private Set<TeamUsers> team_users = new HashSet<>();
TeamUserEntity(桥表):@EmbeddedId private TeamUsersId id;
@ManyToOne
@MapsId("teamId")
@JoinColumn(name = "team_id")
@JsonBackReference
private Team team;
@ManyToOne
@MapsId("userId")
@JoinColumn(name = "user_id")
@JsonManagedReference
private User user;
@Column(name = "active")
private int active;
如您所见,我使用@JsonManagedReference 和@JsonBackReference 来告诉程序查询实体的方向并避免无限递归。
现在,如果我在Team CRUDrepository上运行 get repo.findAll() ,我将获得所有 Team 对象,在内容中我将获得所有桥表数据,它还包括用户详细信息。
但是假设有时如果我想以相反的方式查询数据,我想获取所有用户信息并且对象应该包含所有团队信息,看起来像注释@JsonManagedReference 和 @JsonBackReference阻止了结果。
在现实世界的开发中,我们应该如何管理这里?
解决方案
和@JsonManagedReference
注解@JsonBackReference
用于处理循环引用。它们可用于以双向方式创建 JSON 结构。@JsonManagedReference
注解用于目标 POJO 的子引用,这意味着它是在序列化过程中包含的前向引用,而@JsonBackReference
注解是在序列化过程中省略的反向引用,通常用于相应的子类中。
因此,用@JsonBackReference
此处注释的属性,即Team
中的TeamUsers
,将不会被序列化。这就是为什么当你试图让所有用户都在Team
里面时TeamUsers
,它是行不通的。此外,如果这样做,它将违反它们用于递归访问映射的注释的目的。
如果您想以任何一种方式获取数据,您应该使用@JsonIgnoreProperties
而不是这两个注释。如下更改您的实体类,您将获得所需的输出。
在Team
类中,@JsonIgnoreProperties("team")
在team_users
字段上设置再次忽略team
该字段内部的映射,以避免递归映射。Team
将您的班级更改为:
public class Team {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "TEAM_ID")
private Integer id;
@OneToMany(mappedBy = "team", cascade = CascadeType.ALL, orphanRemoval = true)
@JsonIgnoreProperties("team")
private Set<TeamUsers> team_users = new HashSet<>();
}
同样,在User
类中,@JsonIgnoreProperties("user")
在team_users
字段上设置再次忽略user
该字段内部的映射,避免递归映射。User
将您的班级更改为:
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
@JsonIgnoreProperties("user")
private Set<TeamUsers> team_users = new HashSet<>();
}
最后,在TeamUsers
类中,@JsonIgnoreProperties("team_users")
同时设置team
anduser
字段以再次忽略team_users
这些字段内的映射,以避免递归映射。TeamUsers
将您的班级更改为:
public class TeamUsers {
@EmbeddedId
private TeamUserId id;
@ManyToOne
@MapsId("teamId")
@JoinColumn(name = "team_id")
@JsonIgnoreProperties("team_users")
private Team team;
@ManyToOne
@MapsId("userId")
@JoinColumn(name = "user_id")
@JsonIgnoreProperties("team_users")
private User user;
@Column(name = "active")
private int active;
}
现在,您可以以任何一种方式获取数据,而无需递归映射。
推荐阅读
- sql - SQL(BigQuery) 中 2020 年 5 月 1 日至 2021 年 4 月 30 日之间一周中每一天的计数
- python - 如何使用 Plotly Python 绘制 Mesh3D 子图
- json - 有没有办法快速转换 Json
到 bson 能够将其保存到 mongo 吗? - vespa - 要跟踪哪些指标以确定是否需要添加资源
- image - 使用内在和外在参数将正面图像转换为鸟瞰图
- keras - 在 Tensorflow 中创建自定义 RNN 单元时出错
- nestjs - 如何在@nestjs/mongoose 模式中设置枚举
- c# - 我可以在单个 asp net core 5 项目中结合 react 和 webapi 吗?
- html - 带有选择所有复选框的多选下拉菜单
- javascript - 如何将变量分配为对象内部的值?