다중성
@ManyToOne
, @OneToMany
, @OneToOne
, @ManyToMany
단방향, 양방향
테이블은 외래키 하나로 양쪽 조인이 가능하기 때문에 방향이라는 개념이 없다. 반면에 객체는 참조용 필드가 있는 쪽으로만 참조가 가능하다.이 때 한쪽만 참조하면 단방향, 양쪽이 서로 참조하면 양방향이 된다. 사실 양방향이라는 개념도 단방향이 두 개일 때를 뜻하기 때문에 단방향만 존재한다고 볼 수도 있다.
연관관계의 주인
연관관계의 주인 : 외래키를 관리하는 참조
주인의 반대편 : 외래키에 영향을 주지 않음. 단순 조회만 가능
가장 많이 사용하는 연관관계이다. 다대일의 반대는 일대다 관계이다.
일대다 단방향에서는 1이 연관관계의 주인이다. 그러나 테이블 일대다 관계는 항상 N쪽에 외래키가 있다. 이러한 객체와 테이블의 차이때문에 반대편 테이블의 외래키를 관리하는 특이한 구조가 형성된다. 일대다 관계에서는 @joinColumn
이나 조인 테이블 방식을 꼭 사용해야 한다.
일대다 단방향 매핑의 단점
일대다 단방향은 엔티티가 관리하는 외래키가 다른 테이블에 있기 때문에 연관관계 관리를 위해 추가로 UPDATE SQL을 실행해야 한다는 단점이 있다. 따라서 일대다 단방향 매핑보다는 다대일 양방향 매핑을 권장한다.
일대다 양방향
일대다 양방향 매핑은 공식적으로 존재하는건 아니다. @JoinColumn(insertable=false, updatable=false)
로 읽기 전용 필드를 사용해서 양방향처럼 사용할 수 있다.
일대일 관계는 그 반대도 일대일 관계이다. 주 테이블과 대상 테이블 중에 외래키 선택을 할 수 있다. 외래키에는 데이터베이스 UNIQUE 제약조건이 필요하다. 일대일 단방향 매핑은 다대일 단반향 매핑과 유사하다. 일대일 양방향 매핑도 역시 다대일 양방향 매핑처럼 외래키가 있는 곳을 연관관계의 주인으로 두고, 반대편은 mappedBy
를 적용한다. 일대일 매핑 중 대상 테이블에 외래키 단방향 매핑은 JPA에서 지원하지 않는다. 주 테이블에 외래키를 둔다면 주 테이블만 조회해도 대상 테이블에 데이터가 있는지 확인할 수 있다는 장점이 있다.
관계형 데이터베이스는 정규화된 테이블 2개로 다대다 관계를 표현할 수 없기 때문에 연결 테이블을 추가해서 일대다, 다대일 관계로 풀어내야 한다. 객체는 컬렉션을 사용해서 객체 2개로 다대다 관계 표현이 가능하다. 그러나 다대다 매핑은 연결 테이블에 매핑 정보 외의 추가적인 정보를 담을 수 없기 때문에 실무에서 사용되지 않는다. 대신 연결 테이블을 엔티티로 승격 시켜 다대다 관계를 표현할 수 있다.
@ManyToMany
-> @OneToMany
+ @ManyToOne