작성
·
512
2
안녕하세요
항상 좋은 답변 남겨주셔서 감사합니다
OrderItems까지 같이 조회되는 이유가 궁금해서 글을 적게 되었습니다.
@GetMapping("/api/v1/simple-orders")
public List<Order> ordersV1() {
List<Order> orders = orderService.findOrders(new OrderSearch());
orders.forEach(order ->
{
order.getMember().getName();
order.getDelivery().getStatus();
});
return orders;
}
V1 컨트롤러는 다음과 같습니다.
@Entity
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "orders")
public class Order {
@Id
@GeneratedValue
@Column(name = "order_id")
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "member_id")
private Member member;
@OneToMany(mappedBy = "order", fetch = FetchType.LAZY, cascade = CascadeType.ALL) // order가 만들어지면 orderItem이 만들어지기 때문에 영속성 전이한다.
private List<OrderItem> orderItems = new ArrayList<>();
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
private Delivery delivery;
private LocalDateTime orderDate;
@Enumerated(EnumType.STRING)
private OrderStatus status;
ORDER는 다음과 같습니다.
@Entity
@Getter
@Setter
public class OrderItem {
@Id
@GeneratedValue
@Column(name = "orderitem_id")
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "item_id")
private Item item;
@JsonIgnore
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "order_id")
private Order order;
private int orderPrice;
private int count;
ORDER_ITEM은 다음과 같습니다.
여기서 V1 컨트롤러를 통해서 쿼리를 날리면, 뒤늦게 Lazy Loading을 통해서 Order_Item들이 프록시 초기화가 되는 것처럼 나갑니다.
그런데 실제로는 프록시가 초기화도 되어있지 않습니다.
정리하면 이렇습니다
1. Order_Items는 Lazy Loading 설정이 되어있고, 프록시 객체를 강제 초기화 하는 과정도 없습니다. 그런데 왜 select 쿼리가 나가게 되는 것인지 알려주실 수 있으실까요?
2. orderItem에 대한 select 쿼리가 나갔음에도 불구하고 실제 응답에 있는 값은 null입니다. 이 경우는 어떻게 이해를 해야할까요?
항상 좋은 답변 주셔서 감사합니다!
답변 2
1
0
안녕하세요. ...님
전체 프로젝트를 압축해서 구글 드라이브로 공유해서 링크를 남겨주세요.
구글 드라이브 업로드 방법은 다음을 참고해주세요.
주의: 업로드시 링크에 있는 권한 문제 꼭 확인해주세요
추가로 다음 내용도 코멘트 부탁드립니다.
1. 실행 방법을 알려주세요.
2. 어떻게 문제를 확인할 수 있는지 자세한 설명을 남겨주세요.
감사합니다.
안녕하세요!
답글 달아주셔서 너무 감사합니다.
자답 가능할 것 같습니다!
@OneToMany(mappedBy = "order", fetch = FetchType.LAZY, cascade = CascadeType.ALL) // order가 만들어지면 orderItem이 만들어지기 때문에 영속성 전이한다.
private List<OrderItem> orderItems = new ArrayList<>();
말씀하신 내용 하나하나 확인해보니 요 부분이 문제였던 것 같습니다
OrderItem이 Order에 영속성 전이가 되어서, Order가 select 될 때 OrderItems가 같이 Select 되게 된 것 같습니다.
감사합니다!
@안상혁 cascade 옵션 때문은 아닌 거 같습니다. 실제로 cascade 설정을 하지 않아도 동일하게 마지막에 orderItems 를 가져오는 쿼리를 날리는 것을 확인할 수 있습니다.
debugging 해보니까 응답을 만들기 위해 serialize 를 하는 과정에서 결국 쿼리가 날아가는 거 같던데, 왜 굳이 그런 동작이 이뤄지는지는 아직 잘 모르겠습니다.
저도 같은 내용때문에 고민중입니다ㅜㅜㅜorder 와 조인하는 member, delivery 는 proxy 객체로 넘어가는것을 볼수 있는데 orderItem 은 왜 lazy 강제 초기화 하는 것처럼 쿼리가 날라가는 건지 모르겠습니다. 어딜 이해못하고 있는건지..jpa어렵습니다...
return em.createQuery(
"select o from Order o " +
"join o.member m "
"join o.delivery d "
)
.getResultList();
와...말씀대로 getTotalPrice()메서드에 @JsonIgnore 달아주니 쿼리가 안나가네요!👍