Inner Join VS Left Join
1071
작성한 질문수 8
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 으로 사용되는 이유가 궁금합니다.
-> 이 부분도 어떤 경우에 어떤 코드를 실행해서 그런걸까요? 예제 코드를 작성하고 실행한 다음에 그 결과를 보여주세요.
그럼 답변 기다릴게요^^
강의 관련 외 질문입니다.
0
64
2
SpringBoot4 + Hibernate7 모듈 등록 방법 공유
0
85
1
BeanCreationException
0
86
3
Update 후 UpdateMemberResponse 매핑할 때
0
46
1
트랜잭션을 사용 안 할 때 커넥션은 언제 가져오나요?
0
96
2
페이징 + 검색조건 관련해서 질문드립니다.
0
70
1
Query Dsl Q파일 질문입니다.
0
81
1
루트 쿼리라는것은
0
58
1
메서드를 분리하는 기준
0
61
1
findAllWithMemberDelivery 메서드 질문드립니다.
0
108
3
연관관계 매핑을 안 쓸 경우, 사용해야 하는 전략
0
83
2
fetch join과 영속화와 OSIV의 관계
0
83
2
Distinct 사용 전 결과에 대한 의문
0
113
2
레포지토리 계층에서의 트랜잭션에 대한 의문
0
55
1
영속성 컨텍스트 생명주기의 신기한 부분이 있습니다.
0
77
2
dto 필드 속 엔티티 여부
0
58
1
뷰템플릿 사용 시
0
76
2
Result 클래스 관련 질문
0
56
1
@PostConstruct 프록시 관련 질문드립니다
0
85
1
DTO 대신 Form 사용은 안되나요?
0
133
1
OSIV ON 상태일 때
0
95
1
fetch join VS fetch join 페이징 궁금증
0
179
2
양방향 연관관계 알아보는 법?
0
104
1
16강 17강 간단 정리 이게 맞을까요 ?
0
165
2





