양방향 연관관계

꿀이·2022년 1월 16일
0

양방향 연관관계

테이블에서는 외래키 하나만 있으면 두개의 테이블을 양쪽다 접근이 가능하다. 문제는 객체다.

현재 클래스 상태에서는 Member -> Team으로 갈수는 있지만 Team에서 Member를 알 수가 없다.


mappedBy

member의 팀값을 수정했을 때 와 Team에 있는 members 에 수정이 발생한다고 해보자 그럼 테이블은 어떤걸 기준으로 update을 해야할까? 이런 문제를 해결하기 위해서 연관관계의 주인이라는 개념이 필요하다.

Team에 있는 members를 보자 하나의 팀은 여러명의 Member를 가지고 있으니 oneToMany를 적용했다. 거기에 추가로 mappedBy = "team" 을 적어주면 members라는건 Member의 team에 의해서 관리되어진다는걸 말해준다. List<> members 에 값을 새로 추가해준다고 해서 db에는 변경이 일어나지 않는다. 조회는 가능하다.

db에 값이 안들어간다고 헤맬 수 있다!!!

참고

외래 키가 있는 곳을 주인으로 정해라!!
외래키가 있는곳이 N, 외래키가 없는곳이1 → ManyToXXX 쪽이 연관관계의 주인


양방향 연관관계 주의점

  • 연관관계의 주인에 값을 넣자
  • 양방향 매핑시에 무한 루프 조심

연관관계의 주인에 값을 넣자

연관관계의 주인에 값을 넣어줘야 한다. 아까만든 Member-Team 관계에서 주인은 Member이다. 근데 team에 있는 member List 에 add 하게 되면 외래키가 null로 되어서 참조할 수가 없게된다.

양쪽모두에 값을 넣어주는게 좋은 방법이다.

  • 원래는 Member쪽에만 값을 넣어주면 이후에 team.getMembers를 했을 때 값들이 출력이 된다. jpa가 외래키를 가지고 db에서 값을 가지고 온다 하지만, em.flush, em.clear가 안된상태로 1차 캐시에 객체를 가지고 있을때 문제가 발생할 수 있다.
  • 테스트케이스 작성시에 안맞는 상황이 나올 수 있다.

결론적으로 양쪽에 값을 세팅해주는게 안전한 방법이다.

근데 사람일이라는게... 양쪽다 걸어주는걸 깜빡할 수도 있고... 그래서 Member객체에서 setTeam을 할때 team에도 접근해서 해당 Member를 넣어주는 방법을 추천한다고 한다.
참고
이럴때 메서드 이름을 setTeam으로 하지않고 다른이름으로 만드는걸 추천->딱 그 메서드 이름만 보고는 이게 그냥 관례상 getter_setter 인지 구분이 안감 ex) addTeam()

양방향 매핑시에 무한 루프 조심

toString(),lombok,JSON생성 라이브러리 를 사용할때 무한루프가 발상할 수 있다.

Member 에 toString()을 호출할때 Team에 대한 toString()도 호출하고 Team에는 또 members 리스트가 있어서 여기서도 toString()을 호출한다. 이로인해서 스택오버플로우 발생


양방향 매핑 정리

  • 단방향 매핑만으로도 설계는 끝!!
  • 양방향 매핑은 반대향으로 조회 기능이 필요할때만 추가!!
  • 연관관계의 주인은 외래 키의 위치를 기준으로!! ->성능,운영 측면에서도 이득

    단방향 매핑만 잘해두면 나중에 조회가 필요할때 코드 몇줄만 추가만 해주면 된다. 테이블을 손댈필요 없다!!

profile
내게 맞는 옷을 찾는중🔎

0개의 댓글