-1

I am working on a project. I want to give one to one bidirectional relationship. I am getting infinate loop json. why i do not know. I refereed in internet. i could not get it clearly. please give me a solution.

@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;
    }
}

infinate 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",
..............
}]
Kumaresan Perumal
  • 1,805
  • 25
  • 34
  • `Employee` contains `EmpDetails` field. And `EmpDetails` contain back reference to `Employee`. This is the reason. Check [this](https://stackoverflow.com/questions/7397207/json-net-error-self-referencing-loop-detected-for-type) – zolv Sep 17 '19 at 09:09
  • yeah, please give me a solution. how to overcome this problem? – Kumaresan Perumal Sep 17 '19 at 09:10

2 Answers2

2

Because your Employee entity has a EmpDetails and EmpDetails has a Employee entity. Use @JsonIgnore annotation on the employee field of the EmpDetails entity to make it work

  @OneToOne
  @JsonIgnore
  @JoinColumn(name="EMP_ID")
  private Employee employee;
Rahil Husain
  • 560
  • 3
  • 14
1

When Jackson is trying to serialize your entity to json. He should serialze the employee field. To do that he will try to serialize empDetails field. So again trying to serialize the employee field in this empDetails and like that he is going to be in a circular infinite loop. The solution is prevent serialize the field employee. In the class employee you add @JsonIgnore in employee field.

@OneToOne
@JoinColumn(name="EMP_ID")
@JsonIgnore
 private Employee employee;
Khaled Baklouti
  • 408
  • 2
  • 7