에러 일기

[SPRING] Cannot call sendError() after the response has been committed

재원쓰 2023. 1. 10. 15:55

순환참조 에러이다. 테이블과 테이블이 연관 관계를 맺었을 때, api 응답으로 데이터를 보내줄 경우 보내려는 객체 안에 연관관계 객체가 있고, 그 연관관계 객체 안에 내가 보내려는 객체가 또 있는 상황이 발생했다.

Order 클래스

@Entity
@Table(name = "orders")
@Getter @Setter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Order {
    @Id @GeneratedValue
    @Column(name = "order_id")
    private Long id;

    @ManyToOne(fetch = LAZY)
    @JoinColumn(name = "member_id")
    private Member member; // 🔥 Order 객체에서 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]

}

Member 클래스

@Entity
@Getter @Setter
public class Member {

    @Id @GeneratedValue
    @Column(name = "member_id")
    private Long id;

    private String name;

    @Embedded
    private Address address;

    @OneToMany(mappedBy = "member")
    private List<Order> orders = new ArrayList<>(); // 🔥 여기서 또다시 Order 객체를 불러온다.

}

 

이렇게 계속해서 서로를 불러오는 무한루프에 빠지게 되는데, 이걸 해결하기 위해 @JsonIgnore를 사용할 수 있다.

무한루프에 빠질만한 부분에 선언해준다.

 

Order 클래스(변경 후)

@Entity
@Table(name = "orders")
@Getter @Setter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Order {
    @Id @GeneratedValue
    @Column(name = "order_id")
    private Long id;

    @JsonIgnore
    @ManyToOne(fetch = LAZY)
    @JoinColumn(name = "member_id")
    private Member member; // 🔥 Order 객체에서 Member 객체를 불러온다.

    @JsonIgnore
    @OneToMany(mappedBy = "order", cascade = CascadeType.ALL)
    private List<OrderItem> orderItems = new ArrayList<>();

    @JsonIgnore
    @OneToOne(fetch = LAZY, cascade = CascadeType.ALL)
    @JoinColumn(name = "delivery_id")
    private Delivery delivery;

    private LocalDateTime orderDate; //주문시간

    @Enumerated(EnumType.STRING)
    private OrderStatus status; //주문상태 [ORDER, CANCEL]

}

Member 클래스(변경 후)

@Entity
@Getter @Setter
public class Member {

    @Id @GeneratedValue
    @Column(name = "member_id")
    private Long id;

    private String name;

    @Embedded
    private Address address;

    @JsonIgnore
    @OneToMany(mappedBy = "member")
    private List<Order> orders = new ArrayList<>(); // 🔥 여기서 또다시 Order 객체를 불러온다.

}