작성
·
175
0
@GetMapping("/api/v2/orders")
public List<OrderDto> ordersV2() {
List<Order> orders = orderRepository.findAllByString(new OrderSearch());
return orders.stream()
.map(order -> new OrderDto(order))
.collect(Collectors.toList());
}
@Getter
static class OrderDto {
private Long orderId;
private String name;
private LocalDateTime orderDate;
private Address address;
private List<OrderItem> orderItems;
public OrderDto(Order order) {
orderId = order.getId();
name = order.getMember().getName();
orderDate = order.getOrderDate();
address = order.getDelivery().getAddress();
orderItems = order.getOrderItems();
}
}
안녕하세요!
강의 잘 듣고 있습니다~
제가 OrderDto 안에 있는데 orderItem을 초기화 하지 않았는데, null로 반환되지 않고 db에 있는 값으로 반환이 되어서요..! (jpa 활용2편 강의 섹션 4에선 null로 찍힙니다)
혹시 프록시는 초기화하지 않아도 그대로 값이 응답에 반영되는건가요?
답변 2
0
안녕하세요. chi6465618님
이 부분은 설정에 따라서 달라질 수 있습니다.
프록시 상태의 결과를 null로 반환하는 설정도 있고, 프록시를 초기화해서 데이터를 출력하는 설정도 있습니다.
강의 앞부분에서 이런 부분을 이야기하는데요. 한번 복습해보시고, 만약 그래도 확인이 필요하다면
실제 동작하는 전체 프로젝트를 압축해서 구글 드라이브로 공유해서 링크를 남겨주세요.
구글 드라이브 업로드 방법은 다음을 참고해주세요.
주의: 업로드시 링크에 있는 권한 문제 꼭 확인해주세요
추가로 다음 내용도 코멘트 부탁드립니다.
1. 문제 영역을 실행할 수 있는 방법
2. 문제가 어떻게 나타나는지에 대한 상세한 설명
링크: 공식 서포터즈
링크: 자주하는 질문
감사합니다.
0
안녕하세요, 인프런 AI 인턴입니다. chi6465618님, 문의하신 내용에 대해 답변드립니다.
OrderDto에서 orderItems를 초기화하지 않았는데도 값이 반환되는 경우, JPA의 지연 로딩(Lazy Loading) 특성 때문일 가능성이 높습니다. Order
엔티티의 orderItems
필드가 지연 로딩으로 설정되어 있을 때, 해당 필드에 접근하게 되면 JPA는 해당 필드를 프록시 객체로 초기화 하지 않고, 실제 데이터베이스에서 필요한 데이터를 로딩해서 반환합니다.
DTO의 생성자나 메서드 내에서 엔티티의 지연 로딩 필드에 접근하게 되면, 그 시점에 JPA가 프록시를 초기화하고 실제 데이터를 로딩하기 때문에 예상치 못하게 DB 조회가 발생할 수 있습니다. null이 반환되지 않고 실제 값이 반환된 것은, 해당 DTO를 생성하는 시점에 order.getOrderItems()
메서드를 호출함으로써 프록시가 초기화되고, 연관된 엔티티들의 데이터가 DB로부터 로딩된 결과입니다.
서로 다른 결과가 나타나는 이유는 강의 섹션 환경이나 JPA 구현체의 버전, 트랜잭션의 범위 등 다양한 환경 설정에 따라 달라질 수 있습니다. 확인하고자 하는 경우 해당 엔티티의 @OneToMany
또는 @ManyToOne
등의 지연 로딩 관련 어노테이션 설정을 확인하시길 권장합니다.
추가적으로, DTO 생성 시점에 N+1 문제를 방지하고자 fetch join을 활용하여 관련 엔티티를 한 번에 로딩하는 전략을 사용할 수 있습니다. 이런 방식을 통해 성능을 최적화함과 동시에, 원하지 않는 지연 로딩으로 인한 예기치 않은 데이터베이스 접근을 방지할 수 있습니다.