스택오버플로우 오류해결
문제발생
리뷰에 대한 평점기능을 구현하고 Postman으로 테스트를 했는데 갑자기
스택오버플로우라는 에러가 발생했다
해결방법
스택오버플로우 사이트를 클론코딩을 했지만 스택오버플로우가 뭔지 잘 몰랐던 나는 검색을 하기 시작했다.
스택오버플로우가 뭐지??
Stack Overflow는 Stack 영역의 메모리가 지정된 범위를 넘어갈 때 발생하는 오류라고 한다.
자바를 처음 공부했을 때를 떠올려보면
Stack 메모리는 보통 지역 변수가 저장되는 영역이고
함수에서 지역 변수를 선언하면 지역 변수는 Stack 메모리에 할당되고
함수를 빠져나오면 Stack 메모리에서 해제된다.
즉 스택오버플로우 는
한 함수에서 너무 큰 지역변수를 선언 하거나
함수를 재귀적으로 무한정 호출 하게 되면 stack overflow가 발생한 에러이다.
내 경우는 너무 큰 지역변수를 선언을 한 적이 없으니 재귀함수를 선언했구나 해서 찾아보니
1
2
3
4
5
@PostMapping("/{review-id}/like")//리뷰 좋아요
public ResponseEntity addLike(@PathVariable("review-id") Long reviewId) {
Review likeReview = reviewService.addLike(reviewId);
return new ResponseEntity<>(likeReview, HttpStatus.OK);
}
리턴에서 엔티티인 likeReview를 반환하고 있었다.
Entity를 반환하면 생기는 문제점들이 있지만 그중에서도 나의 경우는
순환참조문제였다.
순환참조는 또 뭐지?? 라고 알아보니
엔티티 클래스 간에 양방향 연관 관계가 있을 경우, 무한 루프가 발생할 수 있다고 한다.
예를 들어, A 엔티티가 B 엔티티를 참조하고 B 엔티티가 다시 A 엔티티를 참조하면
직렬화 시 무한 루프가 발생한다는 것이다.
이 문제를 해결하려면 @JsonIgnore 또는 @JsonManagedReference, @JsonBackReference
어노테이션을 사용하여 직렬화에서 무시할 필드를 지정하거나,
DTO(Data Transfer Object)를 사용하여 엔티티와 분리하면 된다고 한다.
리뷰와 아이템이 양방향 매핑 관계를 가지고 있어서 리턴 값을 entity로 보내니
순환참조로 인해 무한루프가 발생하여 스택오버플로우오류가 났던 것이었다
1
2
3
4
//Review Entity
@ManyToOne
@JoinColumn(name = "ITEM_ID", nullable = false)
private Item item;
1
2
3
//Item Entity
@OneToMany(mappedBy = "item", cascade = CascadeType.REMOVE)
private List<Review> reviews = new ArrayList<>()
이를 해결하는 방법은
@JsonIgnore , @JsonManagedReference, @JsonBackReferenc
이런 애너테이션을 쓸 수 있지만 데이터가 안들어가게 되므로
1
2
3
4
5
6
@PostMapping("/{review-id}/like")//리뷰 좋아요
public ResponseEntity addLike(@PathVariable("review-id") Long reviewId) {
Review likeReview = reviewService.addLike(reviewId);
return new ResponseEntity<>
( mapper.reviewToReviewResponseDto(likeReview), HttpStatus.OK);
}
likeReview를 Dto로 변환시켜서 리턴값으로 보냈더니
오류가 안나고 데이터도 잘 들어가게 되었다!