오류에 대한 콘솔 내용은
2024-10-27T19:17:39.304+09:00 WARN 24252 --- [ecogrow-backend][nio-8080-exec-7] .w.s.m.s.DefaultHandlerExceptionResolver : Ignoring exception, response committed already: org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: Document nesting depth (1001) exceeds the maximum allowed (1000, from StreamWriteConstraints.getMaxNestingDepth())
2024-10-27T19:17:39.304+09:00 WARN 24252 --- [ecogrow-backend][nio-8080-exec-7] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: Document nesting depth (1001) exceeds the maximum allowed (1000, from StreamWriteConstraints.getMaxNestingDepth())]
즉 WasteRecord는 다시 WasteItem 리스트를 참조하면서 무한 순환 참조가 발생하여 JSON 직렬화 시 깊이 제한을 초과하는 문제가 발생.
이를 해결하기 위해 양방향 참조 중 하나를 직력화하지 않도록 설정.
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "waste_record_id")
@JsonIgnore
private WasteRecord wasteRecord;
하지만 여전히 문제가 발생.
이렇게 하면 WasteRecord에서 WasteItem 리스트는 직렬화되지만, WasteItem에서 WaseRecord로의 역참조는 무시되어 순환 참조가 발생하지 않게됨.
양방향 참조 필드를 단순히 무시하고 싶은 경우, @JsonIgnoreProperties를 사용하여 참조 필드를 무시.
@JsonIgnoreProperties("wasteRecord")
private List<WasteItem> wasteItems = new ArrayList<>();
정상적으로 결과 도출 확인.
(1). 엔티티 관계
WasteRecord는 WasteItem 과 일대다 관계를 갖고, 이는 각 WasteRecord 가 여러 개의 WasteItem 항목을 가질 수 있음을 의미.
WasteItem은 WasteRecord 와 다대일 관계를 가지므로 각 WasteItem 은 자신이 속한 WasteRecord 를 알 수 있음.
(2). 양방향 탐색
WasteRecord를 직렬화할 때 직렬 변환기는 wasteItems를 포함한 모든 필드를 포함하게 됨.
wasteItems의 각 WasteItem에 대해 직렬 변환기는 WasteRecord를 다시 참조하는 wasteRecord를 포함한 모든 필드를 포함하게 됨.
즉 WasteRecord -> WasteItem -> WasteRecord -> WasteItem -> (무한히 계속).
(3). JSON 직렬화 주기
시리얼라이저가 'WasteRecord'를 발견하면 'WasteItem' 목록을 포함한 모든 필드를 직렬화하려고 시도.
각 WasteItem에는 상위 WasteRecord에 대한 참조가 포함.
직렬 변환기는 이 참조를 다시 WasteItems를 포함하는 WasteRecord로 따라가며 무한 주기를 생성.
JSON 직렬화에는 중첨된 개체의 깊이에 제한이 있으므로 '문서 중첩 깊이 초과' 오류가 발생.
주석으로 이 체인을 끊음으로 JSON 직렬화 중 순환 참조를 방지하는 동시에 Java 코드에서 양방향 관계를 그대로 유지
@JsonIgnore: WasteRecord가 체인을 WasteItem에 백업하고 루프를 다시 시작하지 않도록 역참조(WasteItem의 WasteRecord)를 무시합니다.
@JsonManagedReference 및 @JsonBackReference: 이는 JSON에서 관리되는 부모-자식 관계를 생성하여 "부모" 측(WasteRecord를 WasteItem으로)만 직렬화하고 "하위 항목에서 재귀를 방지합니다. " 측면(WasteItem에서 WasteRecord까지).