[JPA] 양방향 연관관계(2)

Done is better than perfect·2021년 10월 18일
0

JPA

목록 보기
10/12
post-thumbnail

양방향 연관관계를 이용할 때 가장 많이 하는 실수에 대해 알아보자.

이전 글에서 위와 같은 연관관계를 양방향 연관관계라고 하였고, 이 때 "외래키가 있는 곳을 주인으로 정해라" 라는 규칙에 따라 Member의 team을 연관관계의 주인으로 결정했다.

이 때 다음과 같은 코드를 작성한다고 가정해보자.

Member member = new Member();
member.setUsername("member1");
em.persist(member);

Team team = new Team();
team.setName("TeamA");
team.getMembers().add(member);		// 주목 해야 할 부분

em.persist(team);

의도는 단순하다. member와 team 객체를 생성하고 그 생성한 member가 team에 소속되도록 하고싶어 작성한 코드이다. 이 코드를 실행한 후 DB에는 값이 적절하게 들어갈까? 확인해보자.

MEMBER 테이블에 추가한 데이터를 보니 TEAM_ID 값이 NULL이다. 나의 의도는 TeamA의 ID값인 2가 들어가길 원했는데 왜 안들어갔을까.... 추측해보자

Team의 members는 mappedBy 속성이 붙어 있는데 이는 이 변수가 양방향 연관관계의 주인이 아니라는 뜻이다. 즉, 읽기 전용(가짜 매핑)이므로 이 변수에 member를 아무리 넣어봤자 실제로 Member 테이블엔 아무런 영향을 끼칠 수 없다는 뜻이다.

그러므로 내가 의도한 대로 코드를 수정하면

// team.getMembers().add(member); 이 부분은 사실상 의미가 없는 코드
member.setTeam(team)

위처럼 수정 후 다시 프로그램을 실행해보면?

나의 의도대로 값이 잘 셋팅되있는것을 확인할 수 있다.

그렇다면 여기서 조금 더 생각해볼만한 문제가 있다. 개발할 때 마다 이렇게 연관관계 주인을 잘 찾아서 그 주인에 값을 할당하는것이 좋을까? 앞선 예제는 단순한 두개의 테이블로 예시를 들었지만 실제 우리의 비지니스 로직을 담당하는 수많은 테이블 간의 연관관계를 생각해보면 그리 쉬운 문제만은 아닐 것 같다.

이 문제를 해결할 간단한 방법이 있다...! 그것은 한마디로 말하자면

그냥 연관관계 주인 이런거 고려하지말고 양쪽에 다 넣어

라고 할 수 있겠다! JPA로만 따진다면 분명 연관관계 주인에만 값을 넣어주는것이 맞지만, 객체지향적인 측면에서는 양쪽에 값을 넣어주는것이 맞다.(추가로 연관관계의 주인에만 넣어줬을 때 문제가 발생할 여지가 있다.)

team.getMembers().add(member);
member.setTeam(team)

즉, 위처럼 그냥 양쪽에 다 넣어주는것이 헷갈릴 여지도 없을뿐더러 더 안전하다.
이를 조금 더 깔끔하게 처리하는 방법은 연관관계 편의 메소드를 만들어 사용하는것이다.

public void changeTeam(Team team) {
    this.team = team;
    team.getMembers().add(this);
}

위처럼 Member 클래스에 연관관계 편의 메소드를 작성하여 하나의 메소드 호출을 통해 양쪽에 값을 다 넣을 수 있도록 처리하는것이다. 이렇게 양방향 연관관계에서 흔히 하는 실수와 해결법에 대해 알아보았다. 마지막으로 이를 정리하면


양방향 매핑 정리

  1. 단방향 매핑만으로도 이미 연관관계 매핑은 완료(설계 단계에선)
  2. 양방향 매핑은 반대 방향으로 조회(객체 그래프 탐색) 기능이 추가된 것뿐(필요에 따라 추가, 테이블 구조가 변하는건 아니다)

0개의 댓글