주문 생성 기능을 구현하던 중 failed to lazily initialize a collection of role 발생했다. 희한하게 주문은 정상적으로 생성됐는데 응답에서 403 에러가 났다.

Resolved [org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: failed to lazily initialize a collection of role: com.sparta.delivery.user.User.addressList: could not initialize proxy - no Session]

 

 

user.User.addressList에서 났다길래 address 문제인줄 알고 FetchType.EAGER로 수정하며 삽질을 했는데 해결이 안 됐다.

   // User가 여러 개의 주소를 가질 수 있는 일대다 관계
    @OneToMany(mappedBy = "user", fetch = FetchType.EAGER, orphanRemoval = true)
    private List<UserAddress> addressList = new ArrayList<>();

 

 

장시간 삽질 결과 원인은!

@Getter
@Setter
public class OrderResponseDto {
    private UUID orderId;
    private Long userId;
    private OrderTypeEnum typeEnum;
    private OrderStatusEnum statusEnum;
    private List<OrderItem> orderItems;
    private String request;
    private Integer totalAmount;
}

주문 응답 dto에 orderItems 필드 때문이었다.

 

엔티티 리스트를 dto 리스트로 수정하니 오류가 해결됐다.

List<OrderItemDto> orderItems;

 

 

해결된 이유를 챗GPT한테 물어보니 다음과 같다.

해결된 이유:

  • DTO로 변환:
    • List<OrderItem> 대신 List<OrderItemDto>로 변경하면, DTO는 단순히 데이터 전송을 위한 객체이므로, 엔티티의 지연 로딩 문제를 회피하게 됩니다.
    • DTO를 사용할 때는 이미 필요한 데이터만을 가져와서 설정하고, Hibernate 세션이 닫힌 후에도 추가적인 데이터베이스 접근이 필요하지 않기 때문에 지연 로딩 문제를 방지할 수 있습니다.
  • 즉시 로딩이 필요하지 않음:
    • OrderItemDto는 이미 필요한 데이터를 변환한 후 세션이 닫힌 상태에서 사용되므로, 컬렉션이 즉시 로딩될 필요가 없고, 지연 로딩 오류가 발생하지 않습니다.

+ Recent posts