[JPA]' java.lang.IllegalStateException: Cannot call sendError() after the response has been committed '

2578 ワード

注意:https://velog.io/@youns1121/JPA-java.lang.IllegalStateException-Cannot-call-sendError-after-the-response-has-been-committed
誤り
' java.lang.IllegalStateException: Cannot call sendError() after the response has been committed '
2021-06-15 15:33:24.943 ERROR 17900 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: Infinite recursion (StackOverflowError); nested exception is com.fasterxml.jackson.databind.JsonMappingException: Infinite recursion (StackOverflowError) (through reference chain: com.jpacrud.domain.Member["team"]->com.jpacrud.domain.Team["members"]->org.hibernate.collection.internal.PersistentBag[0]->com.jpacrud.domain.Member["team"]->com.jpacrud.domain.Team["members"]->org.hibernate.collection.internal.PersistentBag[0]->com.jpacrud.domain.Member["team"]->com.jpacrud.domain.Team["members"]->org.hibernate.collection.internal.PersistentBag[0]- with root cause
java.lang.StackOverflowError: null
の原因となる
@GetMapping("/read")/クエリー、READ、メンバー
public Member read(@RequestParam Long memberId) {
Optional member = memberRepository.findById(memberId);
return member.get();
}
ManyToOne,OneToManyは、双方向関係でメンバーエンティティを問合せます.
スプリングのJSON変換を担当するJacksonライブラリはEntityオブジェクトをJSON文字列に変換し、メンバーオブジェクトのTeamフィールドはTeamエンティティを参照します.チームオブジェクトのmembersフィールドでメンバーエンティティを参照し、変換中に同じデータを繰り返し出力する循環参照問題.
解決する
Jackson Annotation Examples
@JsonManagedReference,@JsonBackReferenceを追加
@JsonManagedReference
双方向関係に順方向(子->親)を参照する変数を追加すると、シリアル化に含まれます.
@JsonBackReference
双方向関係で、逆方向(親->子)参照に別名を追加すると、シリアルから除外されます.
Member
@ManyToOne
@JsonManagedReference//ループ参照を避ける
@JoinColumn(name="team_id")
private Team team;
Team
@OneToMany(mappedBy = "team")
@JsonBackReference//ループ参照を避ける
private List members = new ArrayList<>();
DTOを使用して戻る
主な理由は、双方向関係では、エンティティ自体がコントローラから戻るように設計されており、問題が発生した場合、エンティティの変更に柔軟に応答することが困難であるためです.
DTOを作成し、必要なデータをControllerに移動して循環参照の問題を防止
関連関係のリセット
双方向関係は必須ではなく、ビジネスロジックに基づいて再設定する必要があります.