user3364549
user3364549

Reputation: 217

how to Fix spring boot one to many bidirectional infinity loop?

i am try to create a one to many bidirectional mapping using spring boot and spring data jpa please look the below entity

Employer Entity

@Entity  
public class Employer  
{  
private Long id;  
private String employerName;  
private List<Employee> employees;  

@Id  
@GeneratedValue(strategy=GenerationType.AUTO)  
public Long getId()  
{  
    return id;  
}  
public void setId(Long id)  
{  
    this.id = id;  
}  
public String getEmployerName()  
{  
    return employerName;  
}  
public void setEmployerName(String employerName)  
{  
    this.employerName = employerName;  
}  

@OneToMany(cascade=CascadeType.ALL, mappedBy="employer")  
public List<Employee> getEmployees()  
{  
    return employees;  
}  
public void setEmployees(List<Employee> employees)  
{  
    this.employees = employees;  
}  
} 

Employee Entity

@Entity  
public class Employee  
{  
private Long id;  
private String employeeName;  
private Employer employer;  

@Id  
@GeneratedValue(strategy=GenerationType.AUTO)  
public Long getId()  
{  
    return id;  
}  
public void setId(Long id)  
{  
    this.id = id;  
}  
public String getEmployeeName()  
{  
    return employeeName;  
}  
public void setEmployeeName(String employeeName)  
{  
    this.employeeName = employeeName;  
}  
@ManyToOne(cascade=CascadeType.ALL, fetch = FetchType.LAZY)  
public Employer getEmployer()  
{  
    return employer;  
}  
public void setEmployer(Employer employer)  
{  
    this.employer = employer;  
}  
}  

Employer Repo

public interface EmployerServices extends JpaRepository<Employer, Long> {
}

Employee Repo

public interface EmployeeServices extends JpaRepository<Employee, Long> {
}

REST Controller is

 @RestController
 public class Controller {
 @Autowired EmployeeServices employeeServices;
 @Autowired EmployerServices employerServices;
 @GetMapping("/getempr")
 public Object getempr(){
    return employerServices.findOne(1L);
 }
}

now the problem begin start see my out put enter image description here

its look like a infighting loop and my server throwing error getOutputStream() has already been called for this response.

 I used @JsonBackReference & @JsonManagedReference 

annotation but the problem is its working like one to many

 {
   "id":1,
   "employerName":"employer",
   "employees":[
     {"id":1,"employeeName":"emp1"},
     {"id":2,"employeeName":"emp2"}
   ]
}  

if I am trying to get in the concern of many to one like all employee with employer. the output is

 [
  {
   "id":1,
   "employeeName":"emp1"
  },
  {
    "id":2,
    "employeeName":"emp2"}
 ]

its not showing me the employer details.

please suggets me guys what i am doing wrong. thanks in advance!!

Upvotes: 6

Views: 11811

Answers (6)

Pankaj Singh
Pankaj Singh

Reputation: 148

I solved the issue by using @JsonManagedReference and @JsonBackReference json properties. So please change your code like as follows:

@ManyToOne(cascade=CascadeType.ALL, fetch = FetchType.LAZY)  
@JsonManagedReference
public Employer getEmployer()  

@OneToMany(cascade=CascadeType.ALL, mappedBy="employer")  
@JsonBackReference
public List<Employee> getEmployees()  
{ 

Upvotes: 0

sweetpoision
sweetpoision

Reputation: 77

use

@JsonProperty(access = Access.WRITE_ONLY)
private List<Employee> employees;

So that it will ignore employees while printing to JSON in the response (and thus prevents the looping), but will still consider the JSON data (employee list) you pass in the request body so that it is available for persistence.

Upvotes: 0

Rajat Goel
Rajat Goel

Reputation: 173

Change your getEmployer Method like this:

@ManyToOne(cascade=CascadeType.ALL, fetch = FetchType.LAZY)
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
public Employer getEmployer()  
{  
    return employer;  
}

Upvotes: 0

nitin verma
nitin verma

Reputation: 634

with the JSON its a problem with bi-directional mapping. Use the below properties.

@JsonIgnoreProperties("employer")
@JsonIgnoreProperties("employees")

please keep fetching type as eager.

hope this will work.

Upvotes: 6

Afsun Khammadli
Afsun Khammadli

Reputation: 2068

You can solve your issue with two modification with annotations.
Employer.class

@Entity
public class Employer {
    private Long id;
    private String employerName;

    @OneToMany(cascade = CascadeType.ALL,
            mappedBy = "employer",
            orphanRemoval = true)
    private List<Employee> employees;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getEmployerName() {
        return employerName;
    }

    public void setEmployerName(String employerName) {
        this.employerName = employerName;
    }

    public List<Employee> getEmployees() {
        return employees;
    }

    public void setEmployees(List<Employee> employees) {
        this.employees = employees;
    }
}


Employee.class

@Entity
public class Employee {
    private Long id;
    private String employeeName;


    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "employer_id")
    private Employer employer;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getEmployeeName() {
        return employeeName;
    }

    public void setEmployeeName(String employeeName) {
        this.employeeName = employeeName;
    }

    public Employer getEmployer() {
        return employer;
    }

    public void setEmployer(Employer employer) {
        this.employer = employer;
    }
}

For more information please visit this link.

Upvotes: 0

Cepr0
Cepr0

Reputation: 30474

Instead of using @JsonBackReferenceand @JsonManagedReference try to use annotation @JsonIgnoreProperties:

@JsonIgnoreProperties("employer")
private List<Employee> employees;  

@JsonIgnoreProperties("employees")
private Employer employer;  

It prevents Jackson from rendering a specified properties of associated objects.

Upvotes: 10

Related Questions