본문 바로가기
JAVA/JPA

인프런 JPA 5화 연관관계 매핑 기초 "김영한 강사" -PlusUltraCode-

by PlusUltraCode 2024. 7. 20.

연관관계 매핑 기초: 단방향 연관관계와 양방향 연관관계

1. 단방향 연관관계

단방향 연관관계는 한쪽 엔티티에서만 다른 엔티티를 참조하는 방식입니다. 예를 들어, Member 엔티티가 Team 엔티티를 참조하는 경우입니다.

@Entity
public class Member {
    
    @ManyToOne
    @JoinColumn(name = "team_id")
    private Team team;

    // Getter, Setter
}

이렇게 하면 Member 엔티티는 Team 엔티티와 1

관계 중 N 쪽에 해당하게 됩니다. 그렇다면 1쪽 엔티티는 어떻게 작성해야 할까요?

@Entity
public class Team {
    
    @OneToMany(mappedBy = "team")
    private List<Member> members = new ArrayList<>();

    // Getter, Setter
}

2. mappedBy에 대해 알아보자

mappedBy 속성은 양방향 연관관계에서 사용됩니다. 이는 외래 키를 소유하고 있는 쪽을 지정하여 주인(owner)을 설정하는 것입니다. 주인은 외래 키를 관리(등록, 수정)할 수 있고, 주인이 아닌 쪽은 읽기만 가능합니다.

  • 주인만이 연관관계의 외래 키를 관리할 수 있다.
  • 주인이 아닌 쪽은 mappedBy 속성으로 주인을 지정해야 한다.

즉, 1

관계에서 N 엔티티인 Member가 연관관계의 주인이 됩니다.

@Entity
public class Member {
    
    @ManyToOne
    @JoinColumn(name = "team_id")
    private Team team;

    // Getter, Setter
}

@Entity
public class Team {
    
    @OneToMany(mappedBy = "team")
    private List<Member> members = new ArrayList<>();

    // Getter, Setter
}

3. 엔티티 값 설정하기

연관관계 값을 설정할 때는 N쪽 엔티티에 값을 넣어주면 됩니다. 예를 들어, Member 엔티티 안에 Team 객체를 설정하는 방법입니다.

Member member = new Member();
Team team = new Team();
member.setTeam(team);

혹은 양쪽 다 값을 설정해줄 수도 있습니다. 다만 중요한 점은 Team 엔티티 안에 있는 List<Member>도 갱신해줘야 한다는 것입니다.

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

이렇게 하면 Member.setTeam(team)만 해도 양쪽 다 값이 갱신되는 효과를 얻을 수 있습니다. 그리고 getter, setter의 관례에 따라 setTeam보다는 changeTeam으로 메서드명을 바꾸는 것이 좋습니다.

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

4. 무한 루프 방지

양방향 매핑 시 무한 루프를 조심해야 합니다. 이는 toString(), hashCode(), equals(), JSON 변환 시 문제가 될 수 있습니다. Lombok을 사용할 때도 주의해야 합니다.

@Entity
public class Member {
    
    @ManyToOne
    @JoinColumn(name = "team_id")
    private Team team;

    // Getter, Setter
}

@Entity
public class Team {
    
    @OneToMany(mappedBy = "team")
    private List<Member> members = new ArrayList<>();

    // Getter, Setter
}

결론

  • 단방향 연관관계는 한쪽 엔티티에서만 다른 엔티티를 참조합니다.
  • 양방향 연관관계에서는 연관관계의 주인만이 외래 키를 관리할 수 있습니다.
  • 양쪽 모두 값을 설정하는 것이 안정적입니다.
  • 무한 루프를 방지하기 위해 toString(), hashCode(), equals(), JSON 변환 시 주의해야 합니다.