[JPA] 연관관계 매핑 기초

maxxyoung·2022년 7월 25일
0

목표 - 객체의 참조와 테이블의 외래키를 매핑하는 것

방향: '단방향, 양방향' 존재. 예를 들어 회원 -> 팀, 팀 -> 회원 중 한 쪽만 참조하는 것을 단방향. 양쪽 모두 서로 참조하는 것을 양방향.
다중성: '다대일(N:1), 일대다(1:N), 일대일(1:1), 다대다(N:M)' 존재.
연관관계의 주인: 객체를 양방향 연관관계로 만들면 연관관계의 주인을 정해야함. 주로 '다' foreign key를 가지고 있는 쪽.

단방향 연관관계

N:1 단방향 관계의 이해

  • 회원과 팀이 있음
  • 회원은 하나의 팀에만 소속될 수 있음
  • 회원과 팀은 다대일 관계

객체의 연관관계
객체의 연관관계는 참조(주소)로 연관관계를 맺음
참조를 사용하는 객체의 연관관계는 단방향
객체가 서로를 참조하고 싶다면 정확히는 양방향 관계가 아니라 서로 다른 단방향 관계 2개

테이블의 연관관계
외래 키를 사용하는 테이블의 연관관계는 양방향

매핑코드 분석
Member class

@ManyToOne
@JoinColumn(name = "TEAM_ID")
private Team team;
  • Member.team과 MEMBER.TEAM_ID를 매핑하는 것이 연관관계 매핑
  • @ManyToOne 다대일(N:1) 관계라는 매핑 정보.
  • @JoinColumn(name = "TEAM_ID") 외래 키를 매핑할 때 사용. name 속성은 매핑할 외래키 이름을 지정

양방향 연관관계

객체의 연관관계

  • 회원 -> 팀
  • 팀 -> 회원

테이블에서의 관계
데이터베이스 테이블은 외래키 하나로 양방향으로 조회 가능
따라서 데이터베이스에 추가할 것은 없음

매핑코드 분석
Team class

@OneToMany(mappedBy = "team")
private List<Member> members = new ArrayList<Member>();
  • 위에 Member class는 수정없이 그대로인 상태
  • mappedBy 속성은 양방향 매핑일 때 사용, 반대쪽 매핑의 필드 이름을 값으로 넣으주면 됨
  • 반대쪽 매핑이 Member.team이므로 team을 값으로 넣어주면 됨

양방향 연관관계의 주의점
양방향 연관관계를 설정하고 많이 하는 실수
-> 연관관계 주인에는 값을 입력하지 않고, 주인이 아닌 곳에만 값을 입력하는 것

이렇게 설정하면 '다'쪽인 곳에 외래키가 제대로 업데이트 되지 않음
객체까지 고려하여 주인이 아닌 곳에도 값을 입력해주어야함

따라서 객체의 양방향 연관관계는 양쪽 모두 관계를 맺어주자!

양방향 관계에서 한쪽이 수정되어도 다른 한쪽이 수정될 수 있게 리팩토링 해보자

public class Member{

	private Team team;
    public void setTeam(Team team){
    	this.team = team;
        team.getMembers().add(this);

이런식으로 양방향 관계를 설정하는 메소드를 연관관계 편의 메소드라 함

※ 연관관계 편의 메소드 작성시 주의사항

  • 연관관계가 바뀔 때 기존 관계가 유지 되므로 기존 관계를 삭제하는 로직도 필요
    public class Member{
public void setTeam(Team team){
	//기존 팀 관계를 제거
    if(this.team != null){
    	this.team.getMembers().remove(this);
    }
    this.team = team;
    team.getMembers().add(this);
  • toString()시 무한루프 빠지지 않도록 주의. 보통 JSON 변환할 때 자주 나타나고 JSON라이브러리들은 보통 무한루프에 빠지지 않도록 어노테이션이나 기능을 제공함

참고
자바 ORM 표준 JPA 프로그래밍

profile
오직 나만을 위한 글. 틀린 부분 말씀해 주시면 감사드립니다.

0개의 댓글

관련 채용 정보