I'd like to know how to handle serialization with Spring REST with bidirectional relationships. I'm currently using Spring Boot the 1.3.0.BUILD-SNAPSHOT
Currently I'm receiving and internal Server Error stating an infinite recursion on a GET request on the primary class's repository.
It works with two classes where one of which is a Repository. In the example A being the one which has a repository:
@Entity
public class A implements Serializable {
private static final long serialVersionUID = 1L;
@OneToMany(mappedBy = "a", cascade = CascadeType.ALL)
@JsonManagedReference
private List<B> b;
public A() {
}
public List<B> getB() {
return b;
}
public void setCategory(List<B> b) {
this.b = b;
for (B oneB : this.category) {
oneB.setA(this);
}
}
}
@Entity
public class B implements Serializable {
private static final long serialVersionUID = 1L;
@ManyToOne
@JoinColumn(name = "b_column")
@JsonBackReference
@RestResource(rel = "BParent")
private A a;
public B() {
}
public A getA() {
return a;
}
public void setA(A a) {
this.a = a;
}
}
But if I add another class that is inside of B it won't work anymore and I'll get the infinite recursion if I send a GET request to A's repository (C having the same annotations as B on its b property):
@Entity
public class B implements Serializable {
private static final long serialVersionUID = 1L;
@ManyToOne
@JoinColumn(name = "b_column")
@JsonBackReference
@RestResource(rel = "BParent")
private A a;
@OneToMany(mappedBy = "c", cascade = CascadeType.ALL)
@JsonManagedReference
private List<C> c;
public B() {
}
public A getA() {
return a;
}
public void setA(A a) {
this.a = a;
}
}
So from what I have observed I can omit the Jackson annotation in class C on the backreference to B without getting any change in behavior. Is this known behavior or am I missing something?
Update 1
I tried to get rid of the bidirectional relationships between the B and the C object by modifying the B class and removed the back reference on C:
@Entity
public class B implements Serializable {
private static final long serialVersionUID = 1L;
@ManyToOne
@JoinColumn(name = "b_column")
@JsonBackReference
@RestResource(rel = "BParent")
private A a;
//This is now a unidirectional relationship to C
@NotNull
@OneToMany
@JoinColumn(name="b_id", referencedColumnName="id")
private List<C> c;
public B() {
}
public A getA() {
return a;
}
public void setA(A a) {
this.a = a;
}
public List<C> getC() {
return c;
}
public void setC(List<C> c) {
this.c= c;
}
}
While this gets rid of the infinite recursion upon a GET request on A's repository (Hooray!) it also eliminates the possibility store C objects when sending a POST to A's repository (boooh!). This will throw this error message:
org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing
Update 2
I tried to add a repository for the B class. This resulted in another infinite recursion. But this time the application and the IDE just crash because the error is not handled properly.