JPA

연관관계 매핑 기초

taey 2024. 8. 26. 17:55

객체를 테이블에 맞추어 데이터 중심으로 모델링하면, 협력 관계를 만들 수 없다. 

  • 테이블은 외래 키로 조인을 사용해서 연관된 테이블을 찾는다.
  • 객체는 참조를 사용해서 연관된 객체를 찾는다.
  • 테이블은 외래키, 객체는 참조
더보기
//팀 저장
 Team team = new Team();
 team.setName("TeamA");
 em.persist(team);
 
 //회원 저장
 Member member = new Member();
 member.setName("member1");
 
 // 외래키를 직접 다룸
 member.setTeamId(team.getId());
 em.persist(member);
 
 
 
 // 식별자로 다시 조회, 객체 지향적인 방법은 아님
 //조회
 Member findMember = em.find(Member.class, member.getId());
 
 //연관관계가 없음
 Team findTeam = em.find(Team.class, team.getId());

 

단방향 연관 관계

더보기

객체의 참조와 테이블의 외래 키를 매핑

@Entity
 public class Member {
     @Id @GeneratedValue
     private Long id;
     @Column(name = "USERNAME")
     private String name;
     private int age;
    // @Column(name = "TEAM_ID")
    // private Long teamId;
     @ManyToOne
     @JoinColumn(name = "TEAM_ID")
     private Team team;

 

//팀 저장
 Team team = new Team();
 team.setName("TeamA");
 em.persist(team);
 
 //회원 저장
 Member member = new Member();
 member.setName("member1");
 member.setTeam(team); //단방향 연관관계 설정, 참조 저장 (외래키 사용 X, 객체 사용)
 em.persist(member);
 
 
  //조회
 Member findMember = em.find(Member.class, member.getId());
//참조를 사용해서 연관관계 조회
 Team findTeam = findMember.getTeam();

 

양방향 연관 관계

더보기

 

 @Entity
 public class Member {
     @Id @GeneratedValue
     private Long id;
     @Column(name = "USERNAME")
     private String name;
     private int age;
     // Member class에 team 추가
     @ManyToOne
     @JoinColumn(name = "TEAM_ID")
     private Team team;
 … 
 
 
 
 @Entity
 public class Team {
     @Id @GeneratedValue
     private Long id;
     private String name;
     //Team class에 member 컬렉션 추가
     @OneToMany(mappedBy = "team")
     List<Member> members = new ArrayList<Member>();
     …
 }

 

  • 양방향 관계는 단방향 관계 2개이다.
  • 테이블은 외래 키 하나로 두 테이블의 연관 관계를 관리
  • MEMBER.TEAM_ID 외래 키 하나로 양방향 연관관계 가짐
    (양쪽으로 조인 가능)
SELECT *
FROM MEMBER M
JOIN TEAM T ON M.TEAM_ID = T.TEAM_ID

SELECT *
FROM TEAM T
JOIN MEMBER M ON T.TEAM_ID = M.TEAM_ID

 

연관 관계의 주인 (Owner)

양방향 매핑 규칙

  • 객체의 두 관계 중 하나를 연관관계의 주인으로 지정
  • 연관 관계의 주인만이 외래 키를 관리(등록, 수정)
  • 주인이 아닌 쪽은 읽기만 가능
  • 주인은 mappedBy 속성 사용 X
  • 주인이 아니면 mappedBy 속성으로 주인 지정

양방향 매핑 시 가장 많이 하는 실수

- 연관 관계의 주인에 값을 입력하지 않는 것

ex) member의 team_id에 값을 입력하지 않음

Team team = new Team();
 team.setName("TeamA");
 em.persist(team);
 
 Member member = new Member();
 member.setName("member1");
 
 //역방향(주인이 아닌 방향)만 연관관계 설정
 team.getMembers().add(member);
 em.persist(member);

 

- 순수 객체 상태를 고려한다면, 항상 양쪽에 값을 설정하자  
- 이를 위해서, 연관 관계 편의 메소드를 생성하자.

public void addMember(Member member) {
	member.setTeam(this);
    	members.add(member);
}


- 양방향 매핑시에 무한 루프를 조심하자.
   ex) toString(), lombok, JSON 생성 라이브러리 등

 

'JPA' 카테고리의 다른 글

상속관계 매핑  (1) 2024.08.27
다양한 연관관계 매핑  (0) 2024.08.26
기본키 매핑  (0) 2024.08.25
필드와 컬럼 매핑  (0) 2024.08.25
엔티티 매핑  (1) 2024.08.25