주문 생성 기능을 구현하던 중 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는 이미 필요한 데이터를 변환한 후 세션이 닫힌 상태에서 사용되므로, 컬렉션이 즉시 로딩될 필요가 없고, 지연 로딩 오류가 발생하지 않습니다.
'트러블슈팅' 카테고리의 다른 글
| 개발자도구 차단 걸려있는 사이트 뚫는 법 (0) | 2025.03.08 |
|---|---|
| 최종 프로젝트 판짱마켓 트러블 슈팅 (1) - 연관된 객체의 NullPointerException (0) | 2023.09.15 |