Project/DARLING

3. 연관관계 - ManyToOne

Coupon Entity

package so.ego.re_darling.domains.coupon.domain;

import lombok.*;
import so.ego.re_darling.domains.user.domain.User;

import javax.persistence.*;
import java.time.LocalDateTime;

@AllArgsConstructor(access = AccessLevel.PROTECTED)
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Table(name = "coupon")
@Entity
public class Coupon {
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Long id;

  @NonNull private String title;
  private String content;
  private LocalDateTime useDate;

  @Enumerated(value = EnumType.STRING)
  private CouponStatus status;

  @ManyToOne(fetch = FetchType.LAZY)
  @JoinColumn(name = "receiver_id")
  private User receiver;

  @ManyToOne(fetch = FetchType.LAZY)
  @JoinColumn(name = "sender_id")
  private User sender;

  @Builder
  public Coupon(@NonNull String title, String content, LocalDateTime useDate, CouponStatus status) {
    this.title = title;
    this.content = content;
    this.useDate = useDate;
    this.status = status;
  }
}

 

@ManyToOne

예를들어 Coupon 입장에서 receriver User는 1명뿐이고 그 한명이 여러개의 Coupon을 소지할 수 있다. 

여러개를 갖고 있는 Coupon이 Many 이기 때문에  User 와 Coupon 의 연관관계는 @ManyToOne 이다.

단반향으로 설정한 이유는 User를 조회하면서 Coupon 까지 조회할 목적이 없기 때문이다.

반대로 Coupon을 조회할 때는 받는사람인 User의 정보를 표시할 것이기 때문에 User까지 조회할 목적이 있다.

 

더보기
더보기

fetch = FetchType.LAZY *( 나중에 다시 확인해보기 )*

@ManyToOne 의 기본 fetch 전략은 EAGER전략이다(즉시로딩) EAGER 은 해당 Entity를 조회하면 연관된 Entity까지 모두 조회한다. 

단일 정보면 조회하는데도 연관된 Entity까지 조회하며 추가 쿼리가 발생하는 것이 N+1 문제인데 이 문제를 피하기 위해 LAZY를 설정했다. 

 

테스트를 아래와 같이 해봤으나 EAGER, LAZY 둘다 아래와같이 똑같은 쿼리를 출력한다. 

테스트 코드가 잘못된건지 잘 모르겠다

package so.ego.re_darling.domains.coupon.domain;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.transaction.annotation.Transactional;
import so.ego.re_darling.domains.user.domain.User;
import so.ego.re_darling.domains.user.domain.UserRepository;

import java.util.List;

import static org.junit.jupiter.api.Assertions.*;

@DataJpaTest
@Transactional
class CouponTest {
  @Autowired CouponRepository couponRepository;
  @Autowired UserRepository userRepository;

  @Test
  @DisplayName("LAZY전략 실험")
  void lazyTest() {
    User a = userRepository.save(User.builder().socialToken("a").build());
    User b = userRepository.save(User.builder().socialToken("b").build());
    couponRepository.save(Coupon.builder().receiver(a).sender(b).title("non-null").build());
    couponRepository.save(Coupon.builder().receiver(b).sender(a).title("non-null").build());
    System.out.println("=====Find ALL=====");
    List<Coupon> couponList = couponRepository.findAll();
    System.out.println("==========");
    for (Coupon c : couponList) {
      System.out.println(c.getReceiver().getSocialToken());
    }
  }
}

 

 

 

cascade = CascadeType.ALL

@OneToMany, @ManyToOne 에 걸어줄 수 있다. 해당 컬럼이 삭제되면 같이 삭제될 수 있도록 설정한것이다. 

PERSIST,REMOVE 등 옵션이 있지만 보통 ALL을 주고 사용한다.

 

수정 22.02.17

-> @ManyToOne에 걸면 말이 안되는 부분이 커플테이블 - 다이어리 테이블이 있을 경우 다이어리 테이블에서 cascade를 걸어주면

다이어리가 삭제 될 때 커플 까지 삭제 하는것이다. 안쓰는걸로...

 

@JoinColumn

받는사람과 보낸 사람을 구별하기 위해 receiver,sender 를 추가해주었다.

둘다 user 이기 때문에 @JoinColumn 의 이름을 다르게 한다.

name = " " 이 부분에는 user의 pk 와 연결해주는 외래키 컬럼명을 설정해주면 된다.

 

 

반응형

'Project > DARLING' 카테고리의 다른 글

7. CI/CD 계획  (0) 2022.02.09
6. 무엇이 문제일까 ...  (0) 2022.01.25
5. Spring REST Docs 사용  (0) 2022.01.24
4. 연관관계 - OneToMany  (0) 2022.01.23
2. Entity  (0) 2021.12.03