双方向の関係を持つ Spring REST でシリアル化を処理する方法を知りたいです。現在、Spring Boot 1.3.0.BUILD-SNAPSHOT を使用しています。
現在、プライマリ クラスのリポジトリに対する GET リクエストで無限再帰を示す内部サーバー エラーを受信しています。
1 つがリポジトリである 2 つのクラスで動作します。例Aでは、リポジトリを持つものです:
@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;
}
}
しかし、B の内部に別のクラスを追加すると、それは機能しなくなり、A のリポジトリに GET 要求を送信すると無限再帰が発生します (C は b プロパティで B と同じ注釈を持ちます)。
@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;
}
}
したがって、私が観察したことから、動作を変更することなく、B への後方参照でクラス C の Jackson アノテーションを省略できます。これは既知の動作ですか、それとも何か不足していますか?
更新 1
B クラスを変更し、C の後方参照を削除して、B オブジェクトと 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;
}
}
これにより、A のリポジトリでの GET リクエストによる無限再帰がなくなりますが (万歳!)、A のリポジトリに POST を送信するときに C オブジェクトを格納する可能性も排除されます (やった!)。これにより、次のエラー メッセージがスローされます。
org.hibernate.TransientObjectException: オブジェクトが保存されていない一時インスタンスを参照しています - フラッシュする前に一時インスタンスを保存します
更新 2
B クラスのリポジトリを追加しようとしました。これにより、別の無限再帰が発生しました。しかし今回は、エラーが適切に処理されないため、アプリケーションと IDE がクラッシュするだけです。