• RDB는 정규화된 테이블 2개로 다대다 관계를 표현할 수 없기 때문에 연결 테이블을 추가해서 일대다, 다대일 관계로 풀어낸다.
  • 하지만 객체에서는 Collection을 사용해서 객체 2개로 다대다 관계를 나태낼 수 있다.
  • @ManyToMany 사용
  • @JoinTable로 연결 테이블 지정
  • 다대다 매핑: 단방향, 양방향 가능
//Product

@ManyToMany(mappedBy = "products")
private List<Member> members = new ArrayList<>();
//Member

@ManyToMany
@JoinTable(name = "MEMBER_PRODUCT") //MEMBER_PRODUCT라는 연결 테이블이 생성됨
private List<Product> products = new ArrayList<>();

다대다 매핑의 한계

  • 편리해 보이지만 실무에서는 사용해서는 안 된다.
  • 연결 테이블이 단순히 연결만 하고 끝나지 않는다.
  • 매핑 정보만 들어가고 주문시간, 수량같은 필드를 추가할 수 없다.
  • 중간 테이블이 숨겨져 있기 때문에 쿼리가 이상하게 만들어진다.

다대다 한계 극복

  • 연결 테이블용 Entity를 추가한다.
  • @ManyToMany → @OneToMany, @ManyToOne
//MemberProduct

@Id @GeneratedValue
private Long id;

@ManyToOne
@JoinColumn(name = "MEMBER_ID")
private Member member;

@ManyToOne
@JoinColumn(name = "PROUDCT_ID")
private Product product;
//Member

@OneToMany(mappedBy = "member")
private List<MemberProduct> memberProducts = new ArrayList<>();
//Product

@OneToMany(mappedBy = "product")
private List<MemberProduct> memberProducts = new ArrayList<>();
  • 연결 테이블의 PK는 종속 테이블들의 PK들의 복합키로 사용하지 말고 따로 PK를 만들고 FK들은 비식별 관계로 나타낸다.
  • 키가 어딘가에 종속되는 경우 유연성 있게 바꾸기 어렵기 때문
  • 그렇기 때문에 PK 하나만 선언해주는 게 유연성 있게 사용할 수 있다.