깃허브 바로가기
엔티티 연관관계를 매핑할때는 다음 3가지를 고려해야 한다.
다대일 관계의 반대 방향은 항상 일대다 관계이고 일대다 관계의 반대 방향은 항상 다대일 관계이다.
DB테이블의 1, N 관계에서 외래 키는 항상 N쪽에 있다.
따라서 객체의 양방향 관계에서 연관관계의 주인은 항상 N쪽이다.
양방향은 외래 키가 있는 쪽이 연관관계의 주인이다.
아까도 말했듯이 1:N, N:1 연관관계는 항상 N에 외래 키가 있다.
양방향 연관관계는 항상 서로를 참조해야 한다.
양방향 연관관계는 항상 서로 참조해야 한다. 어느 한쪽만 하게되는 순간 양방향 연관관계는 성립되지 않는다.
편의 메소드는 한곳에만 작성하거나 양쪽에 작성을 할 수가 있는데 양쪽에 다 작성하게 되면 무한루프에 빠지므로 주의해야 한다.
다대일 관계의 반대 방향이다. 일대다 관계는 엔티티를 하나 이상 참조할 수가 있으므로 Java Collection중 Collection, List, Set, Map 중에 하나를 사용해야 한다.
하나의 팀은 여러 멤버를 참조할 수 있는데 이런 관계를 일대다 관계라고 한다. 팀은 멤버를 참조하지만 멤버는 팀을 참조하지 않으면 둘의 관계는 단방향이다.
일대다 단방향 매핑의 단점
일대다 단방향 매핑의 단점은 매핑한 객체가 관리하는 외래 키가 다른 테이블에 있다는 점이다.
본인 테이블에 외래 키가 있으면 엔티티의 저장과 연관관계 처리를 INSERT 한번으로 끝낼 수가 있지만, 다른 테이블에 외래키가 존재한다면 연관관계 처리를 위한 UPDATE SQL을 추가로 실행해야 한다.
일대일 관계는 양쪽이 서로 하나의 관계만 갖는다.
일대일 관계의 특징
프록시를 사용할 때 외래 키를 직접 관리하지 않는 일대일 관계는 지연 로딩으로 설정해도 즉시 로딩된다.
프록시에 해당하는 설명은 이후 포스팅에서 다루도록 하겠다.
관계형 데이터베이스는 정규화된 테이블 2개로 다대다 관계를 표현할 수 없다. 그래서 보통 다대다 관계를 일대다, 다대일 관계로 풀어내는 연결 테이블을 사용한다.
그런데 객체는 테이블과는 다르게 객체 2개로 다대다 관계를 만들 수 있다.
@ManyToMany
와 @JoinTable
을 사용해서 연결 테이블을 바로 매핑한 것이다.
@JoinTable
의 속성은 아래와 같다.
@ManyToMany
를 사용하면 연결 테이블을 자동으로 처리해주므로 도메인 모델이 단순해지고 여러 가지로 편리하다.
연결 테이블에 컬럼을 추가하면 더 이상 @ManyToMany 를 사용할 수 없다.
다른 엔티티에는 추가한 컬럼들을 매핑할 수 없기 때문이다.
JPA에서 복합키를 사용하려면 별도의 식별자 클래스를 만들어야 한다. 그리고 엔티티에 @IdClass
를 사용해서 식별자 클래스를 지정하면 된다.
이 식별자 클래스의 특징은 다음과 같다.
@IdClass
를 사용하는 방법 외에 @EmbeddedId
를 사용하는 방법도 있다.부모 테이블의 기본키를 받아서 자신의 기본키 + 외래 키로 사용하는 것을 데이터베이스 용어로 식별 관계라고 한다.
다대일, 일대다, 일대일, 다대다 연관관계 매핑에 관해 살펴봤는데 다대다 연관관계는 사용하기엔 JPA가 다 알아서 처리해주므로 편리했지만 연결 테이블에 필드가 추가된다고 하면 더는 사용할 수 없어서
실무에서 사용하기엔 다대일 매핑이 훨씬 괜찮아 보였다.