Post

스택오버플로우 오류해결

문제발생

리뷰에 대한 평점기능을 구현하고 Postman으로 테스트를 했는데 갑자기

image

스택오버플로우라는 에러가 발생했다

해결방법

스택오버플로우 사이트를 클론코딩을 했지만 스택오버플로우가 뭔지 잘 몰랐던 나는 검색을 하기 시작했다.

스택오버플로우가 뭐지??

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로 변환시켜서 리턴값으로 보냈더니

오류가 안나고 데이터도 잘 들어가게 되었다!

This post is licensed under CC BY 4.0 by the author.