Java Persistence API 연관관계 매핑

개붕이·2025년 1월 7일

JavaPersistenceAPI

목록 보기
4/6
post-thumbnail

연관관계 매핑

아래의 코드는 연관관계가 없는 객체, 참조 대신에 외래키를 그대로 쓰게 되어있다.

// 외래키를 그대로 쓰는 객체의 필드
@Column(name = "TEAM_ID")
private Long teamId;

// 외래키 식별자를 직접 다룸
member.setTeamId(team.getId());

// 조회 시에도 연관관계가 존재하지 않아 식별자로 다시 조회해야함
Team findTeam = em.find(Team.class, member.getTeamId());
  • 데이터 중심의 설계는 협력 관계를 만들 수 없다. (객체 지향적이지 않게됨)
  • 즉, 엔티티 매핑 시에는 연관 관계가 필요하다
  • 테이블 : 외래키로 조인 -> 연관 테이블을 찾음 -> 테이블 내의 값만 활용 가능
  • 객체 : 참조를 사용하여 연관된 객체를 얻음

결국, 데이터 중심 설계에서 객체 지향적 설계로 변경하기 위해서는 연관관계 매핑이 필수적이라는 것.


단방향 연관관계

객체 지향 모델링 시에 객체 연관관계 사용을 위해 새로운 어노테이션을 사용한다.

@ManyToOne
@JoinColumn(name = "TEAM_ID")
private Team team;

예시 속 어노테이션은 다대일 (ManyToOne) 관계에서 팀 테이블 속 매핑되는 컬럼(JoinColumn)을 알려주는 것이다.

저장

  //팀 저장
  Team team = new Team();
  team.setName("TeamA");
  em.persist(team);
  //회원 저장
  Member member = new Member();
  member.setName("member1");
  member.setTeam(team); //단방향 연관관계 설정, 참조 저장
  
  em.persist(member);

저장 시에는 객체를 저장하고 저장 객체의 지정된 테이블에서 PK 값을 찾아와 저장

조회

 //조회
Member findMember = em.find(Member.class, member.getId()); 
//참조를 사용해서 연관관계 조회
Team findTeam = findMember.getTeam(); 

조회 시에는 참조로 연관관계를 조회 (객체 그래프 탐색)

수정

 // 새로운 팀B
  Team teamB = new Team();
  teamB.setName("TeamB");
  em.persist(teamB);
// 회원1에 새로운 팀B 설정
  member.setTeam(teamB);

수정 시에는 연관 관계를 사용하여 새로운 객체로 쉽게 교체 (FK 값 변경)

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

연관관계의 주인은 단방향 매핑과 똑같이 설정함 (@ManyToOne, @JoinColumn)


연관 관계가 아닌 쪽은 @OneToMany(mappedBy = "") 설정을 해줌 (값은 연관관계 주인의 필드명을 사용)

@OneToMany(mappedBy = "team")
private List<Member> members = new ArrayList<>();

양방향 매핑이란 결국 단방향 객체 연관관계 + 반대 방향으로 객체 그래프 탐색이 가능하게 만드는 것이다.


mappedBy ?

  • 객체의 연관관계는 2개
    • 회원 -> 팀 단방향
    • 팀 -> 회원 단방향
  • 테이블의 연관관계는 하나
    • 회원 <-> 팀 양방향

객체의 연관 관계는 단방향 2개다. 반면 테이블의 연관관계는 양방향 1개 (FK 하나로 두 테이블의 연관관계를 정리한다)

즉, 객체 둘 중 하나로 외래키를 관리해야된다는 것이다.

연관관계의 주인

양방향 매핑의 규칙

  • 객체의 두 관계 중 하나를 주인으로 지정
  • 주인만 외래키를 관리 (등록, 수정)
  • 아닌 쪽은 읽기만 가능
  • 주인은 mappedBy 속성 X
  • 아닌 쪽은 mappedBy 로 주인 엔티티의 필드 값을 지정해야함

주인은 어떻게 설정해야하는가

  • 외래키가 존재하는 곳을 주인으로 설정
  • 위의 예시에서는 member 가 주인이 되어야함

양방향 매핑 시에 DB에 반영되게 하려면 주인에 값을 매핑해야함 (순수객체관계 고려 시에는 양쪽 다 입력)


주의점: 양쪽에 값을 설정해주고 (순수 객체 상태)
연관관계 편의 메소드를 생성해주어야한다. (주인 엔티티 생성 시에 양방향 매핑을 구현하는 메소드)


무한 루프를 조심해야함 (toString, lombok, JSON Library 등등)

비즈니스 로직을 기준으로 주인을 설정하지 않고 외래키 위치를 기준으로 주인을 정하자

profile
based on the records

0개의 댓글