public class Order {
@Id @GeneratedValue
@Column(name = "order_id")
private Long id;
@ManyToOne(fetch = LAZY)
@JoinColumn(name = "member_id")
private Member member;
@OneToMany(mappedBy = "order", cascade = CascadeType.ALL)
private List<OrderItem> orderItems = new ArrayList<>();
@OneToOne(fetch = LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "delivery_id")
private Delivery delivery;
private LocalDateTime orderDate; //주문시간
@Enumerated(EnumType.STRING)
private OrderStatus status; //주문상태 [ORDER, CANCEL]
위는 Order클래스이다.
@GetMapping("/api/v1/simple-orders")
public List<Order> ordersV1() {
return orderRepository.findAllByString(new OrderSearch());
}
/api/v1/simple-orders 엔드포인트에 GET 요청을 보내면, 해당 엔드포인트에서 OrderRepository를 통해 검색된 Order 엔터티 목록을 JSON 형식으로 반환하는 코드이다.
물론, 엔티티를 직접 노출하는 것이 좋은 방법은 아니지만 해당 방법을 이용할 때 발생하는 오류에 대해 다뤄보고자 한다.

위와 같이 무한루프가 발생한다!
@ManyToOne(fetch = LAZY)
@JoinColumn(name = "member_id")
private Member member;
@OneToMany(mappedBy = "order", cascade = CascadeType.ALL)
private List<OrderItem> orderItems = new ArrayList<>();
@OneToOne(fetch = LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "delivery_id")
private Delivery delivery;
Order -> Member -> Order -> Member ...
Order -> OrderItems -> Order -> OrderItems ...
Order -> Delivery -> Order -> OrderItems ...
참조하고 있는 엔티티를 계속 순회하면서 무한루프가 발생하게 되는 것이다.
양방향이 걸리는 곳은 한 쪽에 @JsonIgnore 어노테이션을 이용하면 무한루프를 피할 수 있다.
Member - Order
Delivery - Order
OrderItem - Order
세 가지 경우 모두 한쪽에 @JsonIgnore 어노테이션을 이용하면 된다.