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&lt;EmployeeCourse&gt;EmployeeCourse 引用了 EmployeeEmployeeCourse Course: EmployeeCourse 引用了 CourseCourse 引用了 Set&lt;EmployeeCourse&gt;

这意味着当 Jackson 序列化您的 Employees 时,它将序列化所有这些重复的信息。

话虽如此,您现在有三个选择:

    您可以将双向关系转变为单向关系,例如,删除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 中有一个新实体的主要内容,如果未能解决你的问题,请参考以下文章

[JSON].result()

用struts2开发,<result type="json"></result>是啥意思?

json result.json

json result.json

从json对象数组中提取元素

Struts2自定义返回Json类型result