JPA 연관관계 매핑 기초

이상민·2021년 11월 2일
1

JPA

목록 보기
4/8
post-thumbnail

1. 단방향 연관관계

  • 단순히 테이블을 본떠 엔티티를 만든다면 다음처럼 데이터를 삽입해야한다
Team team = new Team();
team.setName("TeamA");
em.persist(team);

Member member = new Member();
member.setUsername("member1");
member.setTeamId(team.getId());
em.persist(member);
  • 테이블을 외래 키로 연관을 가지고 객체는 참조가 가져 패러다임이 다르다

  • 객체 지향적으로 엔티티를 만들려면 다음처럼 단방향 연관관계를 설정할 수 있다

@Entity 
public class Member {
    
    @Id
    private Long id;
    
    private String username;
    
    @ManyToOne
    @JoinColumn(name = "team_id")
    private Team team;
    
    ...
}


// 클라이언트 코드
Team team = new Team();
team.setName("TeamA");
em.persist(team);

Member member = new Member();
member.setUsername("member1");
member.setTeam(team);
em.persist(member);

2. 양방향 연관관계와 연관관계의 주인

2-1. 양방향 연관관계

  • RDB에서는 FK를 사용해 조인을 해서 데이터를 볼 수 있기 때문에, 모든 연관관계가 양방향이다

  • 객체지향에서는 양쪽에서 서로 참조해주지 않으면 단방향이다

  • Team에서 Member 데이터를 가져오기 위해서는 반대로의 연관관계도 설정해줘야한다

@Entity
public class Team {

    @Id
    private Long id;
    
    private String name;
    
    @OneToMany(mappedBy = "team")
    private List<Member> members = new ArrayList<>();
    
    ...
}
  • mappedBy : 연관관계의 주인을 지정한다. 주인은 사용하지 않는다

2-2. 연관관계의 주인

  • RDB : FK와 조인으로 양방향 연관관계 설정

  • 객체지향 : 단방향 참조 2개로 양방향 연관관계 설정

  • FK는 하나인 반면, 참조는 2개이므로 하나의 참조를 정해서 FK를 관리하도록 해야한다
    (주인이 아닌 참조는 읽기만 할 수 있다)

  • 여러 혼란을 피하기 위해 FK를 가지는 테이블과 매핑된 엔티티에 주인을 두는 것이 좋다

// 팀의 멤버로 새로운 멤버를 추가하고 멤버에도 팀 정보(team_id FK)를 저장햐려고 했지만
// team.members는 연관관계의 주인이 아니기 때문에 FK를 삽입하거나 수정할 수 없다 
Member member = new Member();
em.persist(member);

Team team = new Team();
team.getMembers().add(member);
em.persist(team);


// 의도대로 하려면 아래처럼 해야한다 
Team team = new Team();
em.persist(team);

Member member = new Member();
member.setTeam(team);
em.persist(member);

3. 양방향 연관관계 주의점

3-1. 연관관계 편의 메소드

  • 주인이 아닌 참조에 추가하는 것은 데이터베이스에는 영향을 주지 않지만, 객체를 위해 해줘야한다

3-2. 양방향 매핑시 무한 루프

  • toString, lombok toString : 참조 필드 제외

  • JSON 생성 : 엔티티를 컨트롤러에 전달 x

3-3. 양방향 매핑 필요성 생각하기

  • 단방향 매핑만으로 이미 연관관계 매핑은 완료

  • 양방향 매핑은 반대 방향으로 조회(객체 그래픔 탐색) 기능이 추가된 것 뿐

  • 단방향 매핑을 하고 양방향을 나중에 필요할때 추가

profile
편하게 읽기 좋은 단위의 포스트를 추구하는 개발자입니다

0개의 댓글