// Cart.java
@Entity
public class Cart {
@OneToMany(mappedBy = "cart")
private List<CartItem> items;
}
// CartItem.java
@Entity
public class CartItem {
@ManyToOne
@JoinColumn(name = "cart_id")
private Cart cart;
}
// CartService.java
if(!isProductInCart) {
CartItem newCartItem = new CartItem();
newCartItem.setProduct(product);
newCartItem.setCart(cart);
cartItems.add(newCartItem);
cart.setItems(cartItems);
cartRepository.save(cart);
return new SaveResponseDto(cart, true, "Product added to cart successfully");
} else return new SaveResponseDto(null, false, "Product already in cart");
cart 에 cartItem 을 담는 코드다.
잘 담아 DB 에 올바르게 저장했음에도 아래와 같은 오류가 발생했다.
java.lang.IllegalStateException: Cannot call sendError() after the response has been committed
java.lang.StackOverflowError: null
클라이언트로 SaveResponseDto 의 data 필드에 cart 엔티티 객체를 담아서 보내고 있다.
이때 Cart를 직렬화하여 응답으로 보내려고 하면, 다음과 같은 일이 발생한다.
- Cart 객체를 직렬화할 때 CartItem 리스트를 직렬화하려고 시도
- 그런데 CartItem은 다시 Cart 객체를 참조하고 있으므로, CartItem을 직렬화하면서 다시 Cart를 직렬화하려고 시도
- 이 과정이 끝없이 반복되며 순환 참조 발생
이 문제는 직렬화 과정에서 무한 루프를 유발하고, 메모리 초과나 예외(StackOverflowError)가 발생할 수 있다.

자바 프로그램 안에서의 객체를 다른 네트워크를 통해 다른 컴퓨터로 보내거나, DB나 하드웨어에 데이터를 저장하려면 컴퓨터가 처리할 수 있는 바이트 단위로 변환해야 하는데 이를 직렬화라고 한다. 직렬화된 데이터를 원래대로 복원하는 것을 역직렬화라고 한다.
- 값 형식 데이터 : integer, float, charactor 등의 기본 타입
- Object 형식 데이터 : 메모리 주소값을 가진 데이터
자바에서는 값의 입출력을 스트림이라는 데이터 통로를 이용한다. 스트림은 바이트 단위만 이동이 가능하다.
@JsonIgnore 사용@JsonIgnore
private Cart cart; // 순환 참조가 생기는 필드에 대해 무시 처리