Json Result 在 ManyToMany 中有重复项,在 Spring Boot 中有一个新实体
Posted
技术标签:
【中文标题】Json Result 在 ManyToMany 中有重复项,在 Spring Boot 中有一个新实体【英文标题】:Json Result has duplicates in ManyToMany with a New Entity in Spring Boot 【发布时间】:2021-11-19 21:56:46 【问题描述】:我正在尝试使用关系表 EmployeeCourse 获取所有员工,并查看该员工有多少课程。当我在控制器中使用 employeeRepo.findAll() 方法时,我得到如下 JSON 结果:
["firstName":"Pera","lastName":"Peric","employeeCourses":[],"employeeId":1,"firstName":"Marko","lastName":"Markovic","employeeCourses":["id":1,"employee":"firstName":"Marko","lastName":"Markovic","employeeCourses":["id":1,"employee":"firstName":"Marko","lastName":"Markovic","employeeCourses":["id":1,"employee":"firstName":"Marko","lastName":"Markovic","employeeCourses":["id":1,"employee":"firstName":"Marko","lastName":"Markovic","employeeCourses":["id":1,"employee":"firstName":"Marko","lastName":"Markovic","employeeCourses":["id":1,"employee":"firstName":"Marko","lastName":"Markovic","employeeCourses":["id":1,"employee":"firstName":"Marko","lastName":"Markovic","employeeCourses":["id":1,"employee":"firstName":"Marko","lastName":"Markovic","employeeCourses":["id":1,"employee":"firstName":"Marko","lastName":"Markovic","employeeCourses":["id":1,"employee":"firstName":"Marko","lastName":"Markovic","employeeCourses":["id":1,"employee":"firstName":"Marko","lastName":"Markovic","employeeCourses":["id":1,"employee":"firstName":"Marko","lastName":"Markovic","employeeCourses":["id":1,"employee":"firstName":"Marko","lastName":"Markovic","employeeCourses":["id":1,"employee":"firstName":"Marko","lastName":"Markovic","employeeCourses":["id":1,"employee":"firstName":"Marko","lastName":"Markovic","employeeCourses":["id":1,"employee":"firstName":"Marko","lastName":"Markovic","employeeCourses":["id":1,"employee":"firstName":"Marko","lastName":"Markovic","employeeCourses":["id":1,"employee":"firstName":"Marko","lastName":"Markovic","employeeCourses":["id":1,"employee":"firstName":"Marko","lastName":"Markovic","employeeCourses":["id":1,"employee":"firstName":"Marko","lastName":"Markovic","employeeCourses":["id":1,"employee":"firstName":"Marko","lastName":"Markovic","employeeCourses":["id":1,"employee":"firstName":"Marko","lastName":"Markovic","employeeCourses":["id":1,"employee":"firstName":"Marko","lastName":"Markovic","employeeCourses":["id":1,"employee":"firstName":"Marko","lastName":"Markovic","employeeCourses":["id":1,"employee":"firstName":"Marko","lastName":"Markovic","employeeCourses":["id":1,"employee":"firstName":"Marko","lastName":"Markovic","employeeCourses":["id":1,"employee":"firstName":"Marko","lastName":"Markovic","employeeCourses":["id":1,"employee":"firstName":"Marko","lastName":"Markovic","employeeCourses":["id":1,"employee":"firstName":"Marko","lastName":"Markovic","employeeCourses":["id":1,"employee":"firstName":"Marko","lastName":"Markovic","employeeCourses":["id":1,"employee":"firstName":"Marko","lastName":"Markovic","employeeCourses":["id":1,"employee":"firstName":"Marko","lastName":"Markovic","employeeCourses":["id":1,"employee":"firstName":"Marko","lastName":"Markovic","employeeCourses":["id":1,"employee":"firstName":"Marko","lastName":"Markovic","employeeCourses":["id":1,"employee":"firstName":"Marko","lastName":"Markovic","employeeCourses":["id":1,"employee":"firstName":"Marko","lastName":"Markovic","employeeCourses":["id":1,"employee":"firstName":"Marko","lastName":"Markovic","employeeCourses":["id":1,"employee":"firstName":"Marko","lastName":"Markovic","employeeCourses":["id":1,"employee":"firstName":"Marko","lastName":"Markovic","employeeCourses":["id":1,"employee":"firstName":"Marko","lastName":"Markovic","employeeCourses":["id":1,"employee":"firstName":"Marko","lastName":"Markovic","employeeCourses":["id":1,"employee":"firstName":"Marko","lastName":"Markovic","employeeCourses":["id":1,"employee":"firstName":"Marko","lastName":"Markovic","employeeCourses":["id":1,"employee":"firstName":"Marko","lastName":"Markovic","employeeCourses":["id":1,"employee":"firstName":"Marko","lastName":"Markovic","employeeCourses":["id":1,"employee":"firstName":"Marko","lastName":"Markovic","employeeCourses":["id":1,"employee":"firstName":"Marko","lastName":"Markovic","employeeCourses":["id":1,"employee":"firstName":"Marko","lastName":"Markovic","employeeCourses":["id":1,"employee":"firstName":"Marko","lastName":"Markovic","employeeCourses":["id":1,"employee":"firstName":"Marko","lastName":"Markovic","employeeCourses":["id":1,"employee":"firstName":"Marko","lastName":"Markovic","employeeCourses":["id":1,"employee":"firstName":"Marko","lastName":"Markovic","employeeCourses":["id":1,"employee":"firstName":"Marko","lastName":"Markovic","employeeCourses":["id":1,"employee":
为简洁起见,删除了很多行,并且未加载其他实体员工。
我的实体如下所示:
@Entity
public class Employee
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "employee_id")
private Integer id;
private String firstName;
private String lastName;
@OneToMany(mappedBy = "employee", cascade = CascadeType.ALL)
Set<EmployeeCourse> employeeCourses;
// getters and setters implemented
// dont have hashCode() and equals overridden
@Entity
public class EmployeeCourse
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@ManyToOne
@JoinColumn(name = "employee_id")
Employee employee;
@ManyToOne
@JoinColumn(name = "course_id")
Course course;
private Date startDate;
private Date endDate;
//have getter and setters and overridden hashCode() and equals
public class Course
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "course_id")
private Integer id;
private String name;
private String description;
@OneToMany(mappedBy = "course")
Set<EmployeeCourse> employeeCourses;
为什么我有这个双重结果,以及如何获取它们?
【问题讨论】:
【参考方案1】:读取您的 JSON 数据非常困难,但我猜想 double results
我假设您在谈论您的 JSON 响应中的大量 Employee
数据。这是由于双向关系:
Employee
EmployeeCourse
: Employee
引用了 Set<EmployeeCourse>
,EmployeeCourse
引用了 Employee
。
EmployeeCourse
Course
: EmployeeCourse
引用了 Course
,Course
引用了 Set<EmployeeCourse>
。
这意味着当 Jackson 序列化您的 Employee
s 时,它将序列化所有这些重复的信息。
话虽如此,您现在有三个选择:
-
您可以将双向关系转变为单向关系,例如,删除
EmployeeCourse
中的employee
属性。
如果出于某种原因 1. 不可能,那么您可以使用 @JsonIgnore
以便 Jackson 不会序列化它们。
如果 2. 也不可能,您可以考虑使用 DTO。通过控制器返回数据时,通常建议使用 DTO 而不是普通实体。使用 DTO,您可以清楚地定义要包含在对调用者的响应中的任何内容。您甚至可以重新组织模型,使其更好地满足客户的需求。您可以将您的内部模型与您的 API 使用者所知道的模型解耦,从而可以重新设计您的内部模型并仍然保持相同的公共模型。
【讨论】:
我认为 3 可能会解决我的问题,谢谢。 太棒了!之后告诉我结果。【参考方案2】:只需将@JsonIgnor 放在您不想扩展的对象之上。前任。当然,如果您不想扩展 employeeCourses 的结果,那么就做这样的事情
@OneToMany(mappedBy = "course")
@JsonIgnore
Set<EmployeeCourse> employeeCourses;
【讨论】:
这不是我的问题的解决方案,我需要显示所有数据。以上是关于Json Result 在 ManyToMany 中有重复项,在 Spring Boot 中有一个新实体的主要内容,如果未能解决你的问题,请参考以下文章