Spring JPA 엔티티의 연관관계

Yebali·2021년 7월 6일
0

약간의_Spring

목록 보기
16/30

Spring JPA의 엔티티(Entity)들은 대부분 서로 연관관계를 가지고 있습니다.
이런 연관관계를 통해 엔티티간의 관계를 알 수 있고 영속성 컨텍스트 안에서 다른 엔티티의 값들을 쉽게 가져올 수도 있습니다.
Spring JPA에서 이런 연관관계를 어떻게 만드는지 알아봅시다.

연관관계 매핑이란?

객체의 참조와 테이블의 외래키를 매핑하는 것을 의미합니다.
JPA에서는 연관관계에 있는 상태 테이블의 PK를 멤버 변수로 갖지 않고 엔티티 객체 자체를 통째로 참조합니다.


만약 위와 같이 멤버와 팀을 N:1의 관계로 나타내는 엔티티가 있을 때 JPA에서는 어떻게 표현할까요?

Member.java

@Entity
public class Member {

    @Id @GeneratedValue
    @Column(name = "member_id")
    private Long id;
    
    private String username;
    
    private int age;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "team_id")
    private Team team;

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

JPA에서는 상대 테이블의 PK를 멤버 변수로 갖지 않고, 엔티티 객체(Team)를 통째로 가지고 있습니다.
그리고 N:1 관계에서 자신이 Member가 N임을 나타내기 위해 '@ManyToOne' 어노테이션을 사용하고 있습니다.
'FetchType.LAZY'는 성능 향상을 위한 옵션인데 여기서 다루지는 않겠습니다.

  • '@JoinColumn'은 FK를 매핑하기 위해 사용합니다. 'name'속성에는 매핑 할 FK이름을 지정합니다.

  • 'changeTeam'메서드를 별도로 지정한 것은 Member의 Team정보가 수정되었을 때, Member에서의 수정과 Team에서의 수정을 원자적으로 수행시키기 위함 입니다.

그리고 이렇게 메서드를 통해 엔티티의 값을 수정하면 Setter를 사용하여 수정할 때보다 값이 변하는 위치를 찾기 쉬워지기 때문에 디버깅시 이점이 있습니다.

사소한 습관으로 코드의 질을 올려봅시다 :)


Team.java

@Entity
public class Team {

    @Id @GeneratedValue
    @Column(name = "team_id")
    private Long id;
    private String name;

    @OneToMany(mappedBy = "team") //FK가 없는 쪽에 mappedBy 사용을 추천
    private List<Member> members = new ArrayList<>();

    public Team(String name) {
        this.name = name;
    }
}

Team에는 여러명의 Member가 포함될 수 있어 '@OneToMany'와 List<Member>로 1:N관계를 표현합니다.

  • 엔티티에 Null이 있는 것은 좋지 않기 때문에 ArrayList 인스턴스를 넣어 Null을 방지합니다.

연관관계의 주체는 'mappedBy'를 통해 나타낼 수 있습니다.

  • 주체 엔티티는 mappedBy 속성을 사용하지 않습니다.
  • 주체가 아닌 엔티티는 maapedBy 속성을 사용해서 연관관계의 주체를 정할 수 있습니다.

위 코드에서는 Team의 List<Member>는 Member의 'team'와 매핑되므로 ' mappedBy = "team" '로 작성합니다.

실행결과

코드를 실행하면 다음과 같은 테이블이 생성됩니다.(Mysql)

Member 테이블


매핑 관계의 주체가 되는 Member 테이블에는 team_id(FK)가 생겼습니다.


Team 테이블

매핑 관계의 주체가 되지 않는 Team 테이블에는 Member에 대한 정보가 나타나지 않습니다

참고로 @OneToOne 관계는 개발자의 관점으로 주체를 잘 생각해서 FK를 가지고 있어야하는 엔티티를 정해주시면 됩니다

profile
머리에 다 안들어가서 글로 적는 중

0개의 댓글