본문 바로가기
Back/JPA

[JPA] 연관관계 매핑, @OneToMany @ManyToOne @OneToOne @ManyToMany

by 은z 2021. 12. 15.

본 포스팅은 김영한 강사의 자바 ORM 표준 JPA 프로그래밍 '기본편' 강의를 수강하며 정리한 내용임을 밝힌다.

DB 테스트 환경은 H2 데이터베이스, IDE는 인텔리제이(community version)를 사용했다.

 


 

다중성 4가지 종류를 알아볼 차례이다.

  • 다대일 (주인쪽에 걸어주는 것!)
  • 일대다 (일쪽에서 다를 조회하는 로직이 필요하다면 매핑 걸어줄것!)
  • 일대일
  • 다대다 (실무에서는 쓰지 말것)

 

아래에 등장하는 관계 예시들은 게시판(Board)과 게시글(Post)의 관계이다.

 

1. 다대일 @ManyToOne

  • 가장 많이 사용하는 연관관계
  • 다대일 단방향 [N:1] : 주인인 '다'쪽에서는 '일'쪽 참조 가능하나, 반대는 조회도 불가능!
  • 다대일 양방향 [N:1, 1:N] : 서로 참조하면 주인아닌 쪽에서는 조회 가능해짐, 연관관계 편의 메소드를 만들어주면 좋음 (무한 루프 주의!)

 

 

다대일(N:1) 단방향 예시

@Entity
public class Post {
    @Id @GeneratedValue
    @Column(name = "POST_ID")
    private Long id;

    @Column(name = "TITLE")
    private String title;

    @ManyToOne
    @JoinColumn(name = "BOARD_ID")
    private Board board;
    //... getter, setter
}

@Entity
public class Board {
    @Id @GeneratedValue
    private Long id;
    private String title;
    //... getter, setter
}

 

다대일(N:1) 양방향 예시

@Entity 
public class Post {

    @Id @GeneratedValue 
    @Column(name = "POST_ID") 
    private Long id; 

    @Column(name = "TITLE") 
    private String title; 

    @ManyToOne 
    @JoinColumn(name = "BOARD_ID") 
    private Board board; 
    //... getter, setter 
} 


@Entity 
public class Board { 

    @Id @GeneratedValue 
    private Long id; 
    private String title; 

    @OneToMany(mappedBy = "board") 
    List<Post> posts = new ArrayList<>(); 
    //... getter, setter 

}

 

 

2. 일대다 @OneToMany

  • 일대다 단방향 [1:N] : '일'이 연관관계의 주인임, @JoinColumn을 넣어주기(꼭!)
  • 일대다 양방향 [1:N, N:1] : 공식적으로 존재 안함. 이보다는 다대일 양방향('다'쪽이 주인)을 추천한다.

'일' 쪽에서 주인을 맡으면 헷갈리고 운영에도 문제가 생길 수 있다.

왜냐하면 다대일 관계에서 주인은 항상 '다'쪽에 있기때문.

따라서 다대일 양방향을 추천한다. (실무에서는 일대다 거의 쓰지 않는다고 함)

단, 공식적이지는 않으나 일대다 양방향을 하고 싶으면,
@JoinColumn (insertable=false, updatable=false) 이걸 '다'쪽에 걸어주면 조회(읽기)만 가능하게 할 수 있음.

 

 

3. 일대일 @OneToOne

  • 주 테이블이나 대상 테이블, 둘 중 어느곳에 외래키 넣어도 됨.
  • 일대일 단방향 : 지원 안함.
  • 일대일 양방향 : 어느 쪽을 주인으로 둘 지, 종합적으로 판단하고 결정해야 함.

 

4. 다대다 @ManyToMany

  • 실무 사용 금지 
  • 중간 테이블이 숨겨져 있기 때문에 자기도 모르게 복잡한 쿼리가 발생할 수 있음.
  • 다대다를 일대다, 다대일 관계로 풀어서(중간 테이블을 Entity 로 승격) 하는 것이 유연하게 대처할 수 있다.

댓글