为什么双向映射会产生无限循环?

why does bidirectional mapping give infinate loop?

我正在做一个项目。我想给出一对一的双向关系。我得到无限循环 json。为什么我不知道。我在互联网上推荐。我无法清楚地了解它。请给我一个解决方案。

@GetMapping(value = "/employees")
List<Employee> getEmployees() {
    return this.employeeRepository.findAll();
}

@Repository
public interface EmployeeRepository extends JpaRepository<Employee, Long> {

}

package com.example.jpa.model;
import java.io.Serializable;
import java.util.Date;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.Table;

@Entity
@Table(name="EMPLOYEES")
public class Employee implements Serializable {

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="EMP_ID", unique = true, nullable = false)
    private Long empId;

    private String name;

    private String department;

    private Long salary;

    @Column(name="JOINED_ON")
    private Date joinedOn;

    @OneToOne(fetch = FetchType.EAGER, mappedBy = "employee", cascade = CascadeType.ALL)
    private EmpDetails empDetails;

    public Long getEmpId() {
        return empId;
    }

    public void setEmpId(Long empId) {
        this.empId = empId;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDepartment() {
        return department;
    }

    public void setDepartment(String department) {
        this.department = department;
    }

    public Long getSalary() {
        return salary;
    }

    public void setSalary(Long salary) {
        this.salary = salary;
    }

    public Date getJoinedOn() {
        return joinedOn;
    }

    public void setJoinedOn(Date joinedOn) {
        this.joinedOn = joinedOn;
    }

    public EmpDetails getEmpDetails() {
        return empDetails;
    }

    public void setEmpDetails(EmpDetails empDetails) {
        this.empDetails = empDetails;
    }

    @Override
    public String toString() {

        String resp = this.empId+" | "+this.name+" | "+this.department+" | "+this.salary+" | "+this.joinedOn;
        if(this.empDetails != null) {
            resp += "|"+this.empDetails.toString();
        }

        return resp;
    }
}

package com.example.jpa.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;

@Entity
@Table(name="EMP_DETAILS")
public class EmpDetails {

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="ED_ID", unique = true, nullable = false)
    private Long edId;

    private String address;

    private String gender;

    @Column(name="YEARS_OF_SERVICE")
    private Long yearsOfService;

    @Column(name="BANK_ACCOUNT")
    private String bankAccount;

    @OneToOne
    @JoinColumn(name="EMP_ID")
    private Employee employee;

    public Long getEdId() {
        return edId;
    }

    public void setEdId(Long edId) {
        this.edId = edId;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public Long getYearsOfService() {
        return yearsOfService;
    }

    public void setYearsOfService(Long yearsOfService) {
        this.yearsOfService = yearsOfService;
    }

    public String getBankAccount() {
        return bankAccount;
    }

    public void setBankAccount(String bankAccount) {
        this.bankAccount = bankAccount;
    }

    public Employee getEmployee() {
        return employee;
    }

    public void setEmployee(Employee employee) {
        this.employee = employee;
    }

    @Override
    public String toString() {

        return this.gender+" | "+this.address+" | "+this.yearsOfService+" | "+this.bankAccount;
    }
}

无限JSON:

[
    {
        "empId": 1,
        "name": "Nataraja G",
        "department": "Documentation",
        "salary": 10000,
        "joinedOn": "2019-09-17T08:12:24.362+0000",
        "empDetails": {
            "edId": 1,
            "address": "Bangalore",
            "gender": "Male",
            "yearsOfService": 4,
            "bankAccount": "00343466",
            "employee": {
                "empId": 1,
                "name": "Nataraja G",
                "department": "Documentation",
                "salary": 10000,
                "joinedOn": "2019-09-17T08:12:24.362+0000",
                "empDetails": {
                    "edId": 1,
                    "address": "Bangalore",
                    "gender": "Male",
                    "yearsOfService": 4,
                    "bankAccount": "00343466",
                    "employee": {
                        "empId": 1,
                        "name": "Nataraja G",
                        "department": "Documentation",
                        "salary": 10000,
                        "joinedOn": "2019-09-17T08:12:24.362+0000",
                        "empDetails": {
                            "edId": 1,
                            "address": "Bangalore",
                            "gender": "Male",
                            "yearsOfService": 4,
                            "bankAccount": "00343466",
                            "employee": {
                                "empId": 1,
                                "name": "Nataraja G",
..............
}]

因为您的 Employee 实体有一个 EmpDetails 并且 EmpDetails 有一个 Employee 实体。在 EmpDetails 实体的员工字段上使用 @JsonIgnore 注释使其工作

  @OneToOne
  @JsonIgnore
  @JoinColumn(name="EMP_ID")
  private Employee employee;

当 Jackson 试图将您的实体序列化为 json 时。他应该序列化员工字段。为此,他将尝试序列化 empDetails 字段。因此再次尝试序列化此 empDetails 中的员工字段,这样他将处于循环无限循环中。 解决方案是防止序列化现场员工。在 class 员工中,您在员工字段中添加 @JsonIgnore。

@OneToOne
@JoinColumn(name="EMP_ID")
@JsonIgnore
 private Employee employee;