1. @ManyToOne vs @OneToMay

1.1. @ManyToOne?

@ManyToOne은 다대일(Many-to-One) 관계를 의미합니다. 이 어노테이션은 FK를 속성으로 가지는 테이블에 사용합니다.

  • @ManyToOne 사용 예시
@Entity
public class Plan {

    @ManyToOne(fetch = FetchType.LAZY) // Plan의 속성에 user_id가 포함됨. 
    @JoinColumn(name = "user_id") // FK
    private User user;
}

1.2. @OneToMany?

@OneToMany는 일대다(One-to-Many) 관계를 의미합니다. 이 어노테이션은 매핑이 되는 객체를 의미합니다.

@Entity
public class User {

    @OneToMany(mappedBy = "user") // Plan.user 필드에 의해 매핑됨. user는 여러개의 plan을 가질 수 있다.
    private List&lt;Plan> plans = new ArrayList<>();
}

<br>

2. 기억하는 방법

일대다, 다대일 관계는 대부분 한 문장에서 파생됩니다.

user는 여러 개의 plan을 가질 수 있다.

관리자는 여러 개의 게시물을 가질 수 있다.

카테고리는 여러 개의 게시물을 가질 수 있다.

위 문장에서 앞에 위치한 엔티티는 하나(One)만 존재하므로 @OneToMany을 사용하여 뒤의 엔티티를 매핑해주어야합니다.

그리고 뒤에 위치한 엔티티는 여러 개(Many)가 존재할 수 있으므로 @ManyToOne을 사용하여 앞의 엔티티를 매핑해주어야합니다.

<br>

3. 다대다 관계

게시물은 여러 개의 태그를 가질 수 있다.

태그는 여러 개의 게시물을 가질 수 있다.

두 개의 엔티티는 서로가 서로를 여러개 가질 수 있는 관계입니다. 이를 다대다 관계라고하며, 다대다 관계는 중간 테이블을 엔티티로 승격해서 일대다, 다대일로 쪼개야합니다.

쪼개지 않고 다대다 관계로 엔티티를 구성할 경우 ~~~과 같은 문제가 발생하기 때문입니다.

3.1 다대다 관계 분리하는 방법

게시물은 여러 개의 태그를 가질 수 있다.

태그는 여러 개의 게시물을 가질 수 있다.

게시물과 태그는 서로를 여러 개 참조할 수 있는 다대다 관계입니다. 이를 해결하기 위해 중간 엔티티인 게시물-태그 엔티티를 생성하여 위 문장을 다시 작성하겠습니다.

게시물은 여러 개의 게시물-태그를 가질 수 있다.

태그는 여러 개의 게시물-태그를 가질 수 있다.

나누게 되면 서로가 서로를 참조하지 않게 되었습니다. 이제 어디에 어떤 어노테이션을 달아야하는지 보입니다.

enitityannotationmapping entity
게시물@OneToMany게시물-태그
태그@OneToMany게시물-태그
게시물-태그@ManyToOne게시물, 태그

아래는 구현된 코드입니다. 실제 이 블로그를 구현하기 위해 사용한 엔티티입니다.

@Entity
@Getter
@Table(name = "post_tag")
public class PostTag extends BaseTimeEntity {

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Long id;

  @ManyToOne
  @JoinColumn(name = "post_id", nullable = false)
  private Post post;

  @ManyToOne
  @JoinColumn(name = "tag_id", nullable = false)
  private Tag tag;

  public PostTag(Post post, Tag tag) {
    this.post = post;
    this.tag = tag;
  }
}