JPA - 연관관계 매핑
연관관계 매핑 기초
연관관계의 필요성
회원과 팀이 있습니다.
회원은 하나의 팀만 소속될 수있습니다.
회원과 팀은 다대일 관계입니다.
바로 코드로 설명하겠습니다.
객체를 테이블에 맞추어 모델링
@Entity
public class Member {
@Id @GeneratedValue
private Long id;
@Column(name = "USERNAME")
private String name;
@Column(name = "TEAM_ID")
private Long teamId;
}
@Entity
public class Team {
@Id @GeneratedValue
private Long id;
private String name;
}
참조 대신 외래키를 객체에서 그대로 사용합니다.
해당 모델링의 문제점은 멤버만 조회했을땐 팀을 한번더 조회해야합니다.
객체를 테이블에 맞추어 데이터 중심으로 모델링하면, 협력 관계를 만들 수 없게됩니다.
객체지향 모델링
단방향 연관관계
@Entity
public class Member {
@Id @GeneratedValue
private Long id;
@Column(name = "USERNAME")
private String name;
@ManyToOne
@JoinColumn(name = "TEAM_ID")
private Team team;
}
@Entity
public class Team {
@Id @GeneratedValue
private Long id;
private String name;
}
member -> team은 갈수있지만 team -> member로는 조회가 되지않습니다. 한쪽에만 연관관계가 걸려있다하여 단방향 연관관계라 합니다.
양방향 연관 관계시에는
@Entity
public class Team {
@Id @GeneratedValue
private Long id;
private String name;
// 멤버앤티티는 수정할 필요없이 팀에서 member를 참조하면 된다.
@OneToMany(mappedBy = "team")
List<Member> members = new ArrayList<Member>();
}
반대편 team에서도 member를 참조하면 됩니다. (사실상 단방향 연관관계가 2개 맺어진 모습)
객체 연관관계와 테이블의 연관관계의 가장 큰차이
기존 테이블관계에서를 보면 fk를 이용하여 기본이 양방향관계였지만
객체의 경우엔 객체 주소로 연관관계를 맺고 단방향의 연관관계를 보여줍니다.
연관관계의 주인과 mappedBy
fk를 이용한 양방향 연관관계를 기본으로 이용하는 테이블의 관계와 달리 단방향으로 연관을 맺는 객체에서는 연관관계의 주인이 필요합니다.
(객체에서 테이블의 fk를 어디에서 관리할지를 정해줘야한다.)
양방향 매핑
- 객체중 하나를 연관관계의 주인으로 지정해야합니다.
- 연관관계의 주인만이 외래 키를 관리합니다(등록 및 수정)
- 주인이 아닌 쪽은 조회만 가능합니다.
- 주인이 아닌 객체에 mappedBy를 이용하여 주인을 지정합니다.
그럼 문제가 하나 남았습니다.
과연 누구를 주인으로 해야하는가?
외래키가 있는 곳을 주인으로 한다.
@Entity
public class Member {
@Id @GeneratedValue
private Long id;
@Column(name = "USERNAME")
private String name;
@ManyToOne
@JoinColumn(name = "TEAM_ID")
private Team team;
}
@Entity
public class Team {
@Id @GeneratedValue
private Long id;
private String name;
@OneToMany(mappedBy = "team")
List<Member> members = new ArrayList<Member>();
}
의 경우 Member.team이 연관관계의 주인이다.
추가로 단방향매핑으로 설계하고 필요할때 양방향매핑을 추가해도 된다.(테이블에 영향을 주지 않기 때문이다.)
댓글남기기