인프런 커뮤니티 질문&답변
Inner Join VS Left Join
작성
·
1.1K
0
Inner Join 이 발생하려면, @ManyToOne 에서 @JoinColumn 의 nullable =false 이거나,
@ManyToOne.optional=false 로 설정해야한다고 하셨는데요, 이번 강의에서는 이러한 설정이 없었음에도 iniiner join 으로 사용되는 이유가 궁금합니다.
감사합니다.
답변 7
0
안녕하세요. 인프런21님^^
강의에서 제공하는 코드보다는 깔끔하게 새로 예제를 하나 만드시고, 다음 3가지 경우를 테스트해보시겠어요?
1. em.find()
2. JPQL로 inner join
3. JPQL로 left join
그러면 원하는 답을 찾으실 수 있을거에요.
테스트 해보시고 질문 남겨주시면 추가로 도움을 드릴게요.
감사합니다.
0
음..find 는 아니었고요,
아래 코드였습니다.
문득 사용중인 코드가 다를수도 있겠다는 생각이 드네요;;
실전! 스프링 부트와 JPA 활용1을 듣지않고
실전! 스프링 부트와 JPA 활용2를 바로 듣는 중이고요
주신 강의자료에는 OrderReposotiry 코드가 없어서
https://github.com/holyeye/jpabook/blob/master/ch11-jpa-shop/src/main/java/jpabook/jpashop/repository/OrderRepository.java 코드로 실습하고 있습니다.
제가 강의에서 사용하신 코드를 확인해볼수 있을까요?
public List<Order> findAll(OrderSearch orderSearch) {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Order> cq = cb.createQuery(Order.class);
Root<Order> o = cq.from(Order.class);
List<Predicate> criteria = new ArrayList<Predicate>();
//주문 상태 검색
if (orderSearch.getOrderStatus() != null) {
Predicate status = cb.equal(o.get("status"), orderSearch.getOrderStatus());
criteria.add(status);
}
//회원 이름 검색
if (StringUtils.hasText(orderSearch.getMemberName())) {
Join<Order, Member> m = o.join("member", JoinType.INNER); //회원과 조인
Predicate name = cb.like(m.<String>get("name"), "%" + orderSearch.getMemberName() + "%");
criteria.add(name);
}
cq.where(cb.and(criteria.toArray(new Predicate[criteria.size()])));
TypedQuery<Order> query = em.createQuery(cq).setMaxResults(1000); //최대 검색 1000 건으로 제한
return query.getResultList();
}
감사합니다.
0
네 혹시 실행을 어떻게 하셨는지요?
아마 find로만 실행을 해보셨을 건데요.
동일한 조건으로 다음 3가지를 테스트해보시겠어요?
1. em.find()
2. JPQL로 inner join
3. JPQL로 left join
그러면 뭔가 답을 찾으실 수 있을거에요^^
0
네, 감사합니다. 제가 테스트 진행한 내역은 아래와 같습니다. :)
아래 코드는 Delivery 엔티티의 일부인데요, 이 중 order 에 FetchType.LAZY 를 붙이지 않을 경우, @ManyToOne.optional=false 와 @JoinColumn.nullable =false 여부와 관계 없이 항상 LEFT JOIN 이 발생합니다.
(FetchType.LAZY 를 붙일 경우, 정상적으로 Delivery 단건 수행이 진행됩니다. )
책에서는 @ManyToOne.optional=false 와 @JoinColumn.nullable =false 어노테이션으로 제어가 가능한 것으로 이해했었는데요, 제가 잘못 이해한 부분이 있는걸까요?
@JsonIgnore
@OneToOne(mappedBy = "delivery", fetch = FetchType.LAZY)
private Order order;
실제 사용된 코드는 아래와 같습니다 .
@Entity
@Table(name = "ORDERS")
@Getter
@Setter
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", cascade = CascadeType.ALL)
private List<OrderItem> orderItems = new ArrayList<OrderItem>();
@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "DELIVERY_ID", nullable = false)
// @JoinColumn(name = "DELIVERY_ID")
// @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY, optional = false)
// @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
// @JoinColumn(name = "DELIVERY_ID")
private Delivery delivery;
private LocalDateTime orderDate;
@Enumerated(EnumType.STRING)
private OrderStatus status; // [ORDER, CANCEL]
// 이하 생략...
Delivery 엔티티 코드는 아래와 같습니다.
@Entity
public class Delivery {
@Id @GeneratedValue
@Column(name = "DELIVERY_ID")
private Long id;
@JsonIgnore
@OneToOne(mappedBy = "delivery", fetch = FetchType.LAZY)
private Order order;
@Embedded
private Address address;
@Enumerated(EnumType.STRING)
private DeliveryStatus status; //ENUM [READY(준비), COMP(배송)]
// 이하 생략...
이렇게 실행할 경우 , 항상 LEFT JOIN 이 발생합니다.
감사합니다.
0
네 잘 찾아주셔서 감사합니다^^
제가 바로 답을 드릴 수도 있지만, 코드로 직접 짜보면서 각각의 차이를 느껴보아야 진정한 배움이 있습니다.
그래서 앞서 질문 드린 것 처럼 1,2번을 예제 코드로 만들어서 각각 실행해보시겠어요?
그리고 1번은 어떤 문맥에서 어떤 경우에만 적용되는지 코드로 한번 확인해보시겠어요?
그럼 답변 기다릴게요^^
0
안녕하세요 강사님 :)
1) @ManyToOne 에서 @JoinColumn 의 nullable =false 이거나, @ManyToOne.optional=false 로 설정해야한다고 하셨는데요 ==> 이 부분은 저술하신 책 298 페이지의 내용입니다
2) 이번 강의에서는 이러한 설정이 없었음에도 iniiner join 으로 사용되는 이유가 궁금합니다.
==> 이번 강의 v2, v3 의 내용입니다.
JPA 경험이 거의 없이 짧은 시간에 많은 공부를 하려다보니 오히려 헷갈리기도 하는것 같네요 ㅎㅎ
많은 조언을 부탁드립니다. 감사합니다.
0
안녕하세요. 인프런21님
Inner Join 이 발생하려면, @ManyToOne 에서 @JoinColumn 의 nullable =false 이거나, @ManyToOne.optional=false 로 설정해야한다고 하셨는데요. -> 이 부분은 혹시 어떤 경우를 말하는 걸까요? 대략 감이 오기는 하는데 정확한 답을 위해서 다시 물어보아요. 예제 코드를 작성하고 실행한 다음에 그 결과를 보여주세요.
이번 강의에서는 이러한 설정이 없었음에도 iniiner join 으로 사용되는 이유가 궁금합니다.
-> 이 부분도 어떤 경우에 어떤 코드를 실행해서 그런걸까요? 예제 코드를 작성하고 실행한 다음에 그 결과를 보여주세요.
그럼 답변 기다릴게요^^





