Spring JPA[연관관계 주인]
양방향 연관관계
양방향 연관관계에서는 양쪽 엔터티 간의 관계를 맺어주기 위해 두 엔터티 간에 매핑이 필요합니다.
이 때 한 엔터티가 다른 엔터티와의 관계를 주도하는 주인 역할을 하게 되는데, 이것을 연관관계의 주인이라고 합니다.
양방향 연관관계에서는 주인을 명시적으로 지정해주어야 하는데, 이때 사용되는 속성이 mappedBy입니다.
코드 예제
Member.class
1
2
3
4
5
6
7
8
9
10
11
@Entity
public class Member {
@Id @GeneratedValue
private Long id;
@Column(name = "USERNAME")
private String name;
private int age;
@ManyToOne
@JoinColumn(name = "TEAM_ID")
private Team team;
}
Team.class
1
2
3
4
5
6
7
8
9
@Entity
public class Team {
@Id @GeneratedValue
private Long id;
private String name;
@OneToMany(mappedBy = "team")
List<Member> members = new ArrayList<Member>();
}
위의 예제코드를 보면, Team.class부분에 mappedBy라는 옵션으로 인해 Team이라는 class가 연관관계의 주인이라는걸 명시하고 있습니다.
연관관계 주인이 설정된 클래스는 데이터베이스 테이블에서 외래 키 관리 등의 책임을 가지게 됩니다.
이것은 JPA에게 해당 필드를 통해 양방향 연관관계를 매핑하고 관리하는 역할을 할 것임을 나타냅니다.
즉, Team 엔터티는 데이터베이스 테이블에서 외래 키 관리 및 다양한 연관관계 측면에서 주인의 역할을 수행합니다.
따라서 이 설정을 통해 양방향 연관관계를 정확하게 매핑하고 데이터 일관성을 유지할 수 있게 됩니다.
활용법
연관관계의 주인이 되면 Member.class에서 Team.class로 조회도 가능하고, Team.class 에서 Member.class 쪽으로 역방향 조회도 가능해 집니다.
예시
1
2
3
//조회
Team findTeam = em.find(Team.class, team.getId());
int memberSize = findTeam.getMembers().size(); //역방향 조회
연관관계 주인(Owner)
그럼 양방향 연관관계에서는 연관관계의 주인이 왜 필요한지에 대해 알아보겠습니다.
연관관계의 주인이 필요한 이유는 데이터베이스에서의 외래 키 관리와 관계 매핑에 있습니다.
연관관계 주인을 명시함으로써 데이터베이스 테이블 간의 외래 키를 정의하고 관리하여 데이터베이스 무결성을 보장하며, JPA에서는 양방향 관계를 효과적으로 매핑하고 조회할 수 있기 때문에 연관관계의 주인(Owner)이 필요합니다.
그럼 테이블과 객체를 기준으로 살펴보겠습니다.
테이블 기준
Member <-> Team
객체 기준
Member -> Team
Team -> Member
테이블 기준으로 보면 양방향이라는 말과 같이 한번에 서로서로 참조를 하고 있습니다.
하지만 객체 기준으로 보면, 단방향으로 2번 참조하고 있습니다.
이처럼 양방향이라는 것은 존재하지 않습니다.
단지, 단방향 연관관계를 2번 적용함으로써 양방향 처럼 보이게 하는 것 입니다.
양방향 매핑 규칙 : Owner
양방향 연관관계 매핑 시, 준수 해야할 규칙이 존재하는데, 아래와 같습니다.
- 연관관계의 주인만이 외래 키를 관리합니다. ( 등록, 수정 )
- 주인이 아닌쪽은 읽기만 가능합니다.
- 주인은 mappedBy 속성을 사용하지 않습니다.
- 주인이 아니면 maapedBy 속성으로 주인을 지정합니다.
주의점
양방향 연관관계 매핑 시, 비즈니스 로직을 기준으로 연관관계의 주인을 설정하면 안됩니다.
반드시, 연관관계의 주인은 외래 키의 위치를 기준으로 정해야합니다.
그 이유는 데이터베이스에서 외래 키를 어떤 테이블이 관리할지 결정해야 하기 때문입니다.
외래 키는 주인 엔터티의 테이블에 속하며, 이를 통해 데이터베이스의 무결성을 유지할 수 있습니다.
따라서 어떤 엔터티가 외래 키를 소유할지에 따라 연관관계 주인이 결정됩니다.
결론
무작정 처음 설계 시, 양방향 매핑으로 해버리는 것은 좋지 않습니다.
양방향 매핑은 단지, 역으로 조회할 수 있는 기능만 추가되는 것 뿐이기에, 객체입장에서도 딱히 좋은건 없습니다.
또한, 단방향 매핑만으로도 이미 연관관계 설정이 끝난겁니다.
그래서 처음 설계시 잘 설계하여야 하고, 추 후에 양방향이 필요하다 싶으면, 그때 추가해도 늦지 않습니다.
그리고 연관관계 주인 설정시 절때 비즈니스 로직에 따라 주인을 맺어주면 안됩니다.
되도록이면 외래키의 위치를 기준으로 정해야합니다.