v2 api의 delivery 쿼리 조회문
안녕하세요 영한님! 간단한 주문 조회v2 질문이 있습니다.
@GetMapping("/api/v2/simple-orders")
public Result ordersV2() {
List<Order> orders = orderService.findAll(new OrderSearch());//프록시가 들어있는 orde 객체
List<SimpleOrderDto> collect = orders.stream().map(o -> new SimpleOrderDto(o.getId(), o.getMember().getName(),
o.getOrderDate(), o.getStatus(), o.getDelivery().getAddress())).
collect(Collectors.toList());
return new Result(collect);
}
위의 v2 api를 실행하면 문제없이 5개의 쿼리문이 나가는 것을 확인했습니다.
name을 조회하는 쿼리는 예상했던데로 단순 조회 쿼리인
select
member0_.member_id as member_i1_5_0_,
member0_.city as city2_5_0_,
member0_.street as street3_5_0_,
member0_.zipcode as zipcode4_5_0_,
member0_.name as name5_5_0_
from
member member0_
where
member0_.member_id=?
와 같이 나가지만.
delivery 엔티티에 접근할때
select
delivery0_.delivery_id as delivery1_2_0_,
delivery0_.city as city2_2_0_,
delivery0_.street as street3_2_0_,
delivery0_.zipcode as zipcode4_2_0_,
delivery0_.status as status5_2_0_,
order1_.orders_id as orders_i1_6_1_,
order1_.delivery_id as delivery4_6_1_,
order1_.member_id as member_i5_6_1_,
order1_.order_date as order_da2_6_1_,
order1_.status as status3_6_1_
from
delivery delivery0_
left outer join
orders order1_
on delivery0_.delivery_id=order1_.delivery_id
where
delivery0_.delivery_id=?
위와 같이 외부 조인문이 나가는 것을 확인했습니다. 마치 패치조인을 한거 같은 전혀 예상치 못한 쿼리문이여서 질문을 드립니다. 또한 모두 lazy로 설정을 했습니다.
혹시 데이터베이스의 방언차이 때문일까요? mysql 사용중입니다.
답변 4
1
안녕하세요. 상운님^^
JPA에서 @OneToOne 관계에서는 기능의 한계로 본인이 FK를 가지고 있지 않은 이상, 항상 즉시로딩으로 동작합니다.
다음 강의를 참고해주세요.
추가로 @OneToOne 관계에서 한계에 대한 더 자세한 대응 방안은 다음 질문을 참고해주세요
https://www.inflearn.com/questions/40670
https://www.inflearn.com/questions/224187
감사합니다.
0
확인 해보니 상품 엔티티도 외부조인이 발생합니다..ㅠ
주문 엔티티
@Entity
@Getter @Setter
@Table(name = "orders")
public class Order {
@Id @GeneratedValue
@Column(name = "orders_id")
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "member_id")
private Member member;
@OneToMany(mappedBy = "order", cascade = CascadeType.ALL)
private List<OrderItem> orderItems = new ArrayList<>();
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "delivery_id")
private Delivery delivery;
private LocalDateTime orderDate;
@Enumerated(EnumType.STRING)
private OrderStatus status;
/**
*
* 연관 관계 편의 메서드
*/
public void setMember(Member member) {
this.member = member;
member.getOrders().add(this);
}
public void addOrderItem(OrderItem orderItem) {
this.orderItems.add(orderItem);
orderItem.setOrder(this);
}
public void setDelivery() {
this.delivery = delivery;
delivery.setOrder(this);
}
/**
* 생성 메서드
*/
public static Order createOrder(Member member, Delivery delivery, OrderItem... orderItem) {
Order order = new Order();
order.setMember(member);
order.setDelivery(delivery);
for (OrderItem item : orderItem) {
order.addOrderItem(item);
}
order.setOrderDate(LocalDateTime.now());
order.setStatus(OrderStatus.ORDER);
return order;
}
/**
* 취소 메소드
*/
public int getSum() {
int sum = 0;
for (OrderItem orderItem : this.orderItems) {
sum += orderItem.totalPrice();
}
return sum;
}
public void cancel() {
if (this.delivery.getStatus() == DeliveryStatus.COMP) {
throw new IllegalStateException("이미 배송이 완료됬습니다.");
}
setStatus(OrderStatus.CANCEL);
for (OrderItem orderItem : this.orderItems) {
orderItem.cancel();
}
}
}
배송 엔티티
@Entity
@Getter @Setter
public class Delivery {
@Id @GeneratedValue
@Column(name = "delivery_id")
private Long id;
@JsonIgnore
@OneToOne(mappedBy = "delivery")
private Order order;
@Embedded
private Address address;
@Enumerated(EnumType.STRING)
private DeliveryStatus status;
}
상품 엔티티
@Service
@RequiredArgsConstructor
@Transactional
public class ItemService {
private final ItemRepository itemRepository;
public Long join(Item item) {
itemRepository.saveItem(item);
return item.getId();
}
public Item findOne(Long itemId) {
return itemRepository.findItem(itemId);
}
public List<Item> findAll() {
return itemRepository.findItems();
}
@Transactional
public void edit(ItemForm itemForm) {
Book book = (Book)findOne(itemForm.getId());
book.setName(itemForm.getName());
book.setPrice(itemForm.getPrice());
book.setStockQuantity(itemForm.getStockQuantity());
book.setAuthor(itemForm.getAuthor());
book.setIsbn(itemForm.getIsbn());
}
}
강의 관련 외 질문입니다.
0
67
2
SpringBoot4 + Hibernate7 모듈 등록 방법 공유
0
92
1
BeanCreationException
0
91
3
Update 후 UpdateMemberResponse 매핑할 때
0
50
1
트랜잭션을 사용 안 할 때 커넥션은 언제 가져오나요?
0
101
2
페이징 + 검색조건 관련해서 질문드립니다.
0
70
1
Query Dsl Q파일 질문입니다.
0
84
1
루트 쿼리라는것은
0
59
1
메서드를 분리하는 기준
0
64
1
findAllWithMemberDelivery 메서드 질문드립니다.
0
110
3
연관관계 매핑을 안 쓸 경우, 사용해야 하는 전략
0
86
2
fetch join과 영속화와 OSIV의 관계
0
86
2
Distinct 사용 전 결과에 대한 의문
0
116
2
레포지토리 계층에서의 트랜잭션에 대한 의문
0
59
1
영속성 컨텍스트 생명주기의 신기한 부분이 있습니다.
0
78
2
dto 필드 속 엔티티 여부
0
60
1
뷰템플릿 사용 시
0
77
2
Result 클래스 관련 질문
0
56
1
@PostConstruct 프록시 관련 질문드립니다
0
86
1
DTO 대신 Form 사용은 안되나요?
0
138
1
OSIV ON 상태일 때
0
96
1
fetch join VS fetch join 페이징 궁금증
0
185
2
양방향 연관관계 알아보는 법?
0
106
1
16강 17강 간단 정리 이게 맞을까요 ?
0
165
2





