[TIL] JPA Entity 연관 관계 맵핑

정석·2024년 8월 21일

TIL

목록 보기
24/40
post-thumbnail

🧑🏻‍💻 예시 상황

  • 회원과 팀 테이블이 있다고 가정.
  • 여러명의 회원이 하나의 팀에 속해있다.

이 때 연관 관계를 어떻게 맵핑할까?

JPA를 활용한 연관관계 맵핑에서
데이터베이스의 테이블끼리 연관관계자바에서 객체끼리의 연관관계의 차이를 알고 가야한다.

데이터베이스에서의 연관관계

이렇게 한명이 회원에 대한 팀 정보를 팀 테이블의 id 를 외래키로 사용하는 구조로 되어 있다.
여기서 회원 여러명이 하나의 팀에 소속되므로 N:1(다대일) 의 관계가 된다.

FK 외래키를 활용해 각자의 테이블에서 다른 테이블과 조인을 할 수 있다.

  • 회원 테이블을 기준으로 조인
    SELECT *
    FROM 회원
    JOIN 팀 ON 회원.team_id = 팀.team_id
  • 팀 테이블을 기준으로 조인
    SELECT *
    FROM 팀
    JOIN 회원 ON 팀.team_id = 회원.team_id

결국 한개의 외래키로 양방향 조인이 가능하다.
근데 객체에선 당연 되지 않는다! 그래서 JPA로 연관관계를 맵핑할 때 따로 방법이 있는 거다!
우선 객체에서는 어떻게 되는지 보자.

객체에서의 연관관계


회원 객체를 만들 때 회원.team 필드에 원하는 팀 객체를 넣으면 팀 정보를 주입할 수 있다.

회원 클래스에서 팀 정보를 가져오려면 회원.getTeam() 를 통해 가져올 수 있다.
그렇다면 팀 클래스에서 회원 정보를 가져오려면?

방법이 없다.

여기서 알 수 있는 건 아무리 다른 객체의 값을 필드값으로 넣어 줘도 객체는 단방향 관계인 것이다.

그럼 이 문제를 어떻게 JPA로 해결할 수 있을까.

  1. 팀 객체 내에서 List members 필드를 생성해준다.
  2. 생성된 List 필드에 어노테이션을 통해 양방향 연관관계 라고 알려준다.

실습

  • 회원 엔티티
public class Member {
	@Id
    @Column (name = "member_id")
    private String id;
    
    private String username;
    
    @ManyToOne // 다대일
    @JoinColumn(name = "team_id")  // 팀 테이블의 id 값을 사용한다!
    private Team team;
    
    // 팀 객체 주입
    public void setTeam(Team team) {
    	this.team = team;
    }
}
  • 팀 엔티티
public class Team {
	@Id
    @Column (name = "team_id")
    private String id;
    
    private String name;
    
    @OneToMany (mapped by = "team") // 중요!
    private List<Member> members = new ArrayList<>();
    }
}

@OneToMany (mapped by = "team") 해당 어노테이션을 통해

"연관관계의 주인은 team 이라는 필드를 가진 쪽이 주인입니다" 라는 의미를 가지고 있다.

연관관계의 주인 ?

연관관계의 주인은 외래 키 관리자를 선택하는 것이다.
여기서 헷갈릴 수 있는 게 외래키 자체를 팀 테이블의 FK 를 가져다 쓰니까 외래키 관리는 팀에서 관리해야하는 거 아닐까? 란 생각이 들 수 있다.

하지만, 외래키의 주인은 외래키가 있는 곳 으로 정해야 한다. 즉, 회원 엔티티가 연관관계의 주인이 된다.

다대일, 일대다에서
항상 쪽이 외래 키를 가지므로, 연관관계의 주인은 항상 쪽이다.


참고 서적 : 자바 ORM 표준 JPA 프로그래밍 - 김영한

0개의 댓글