Post

(JPA)일다대 매핑

연관관계 매핑(1:N)

일대다 객체 연관관계

  • 1이 연관관계의 주인
  • 권장되지 않는 매핑 방법

Member

1
2
3
4
5
6
7
8
9
@Entity
public class Member {
	@Id
	@GeneratedValue
	@Column(name = "member_id")
	private Long id;
	@Column(name = "username")
	private String username;
}
  • 멤버 객체

Team

1
2
3
4
5
6
7
8
9
10
11
12
@Entity
public class Team {
	@Id
	@GeneratedValue
	@Column(name = "team_id")
	private Long id;
	private String name;

	@OneToMany
	@JoinColumn(name = "team_id")
	private List<Member> members = new ArrayList<>();
}
  • 팀 객체

저장

1
2
3
4
5
6
7
8
9
10
11
Member member = new Member();
member.setUsername("member1");

em.persist(member);

Team team = new Team();
team.setName("teamA");

team.getMember().add(member);

em.persist(team);
  • DB에 저장은 문제 없이 잘 되나, Update Query 가 하나 더 발생된다.
update member
set team_id=?
where member_id=?
  • 성능 상으로 아주 큰 문제는 아니지만, 어찌되었든 Query가 한번 더 발생하는 손실이 있고 추가적으로 JPA 숙련된 사람일지라도 코드만 보고 동작 방식을 한눈에 알아보기 어렵다.

정리

  • 연관관계 관리를 위해 추가적인 UPDATE SQL 실행
  • 일대다 단반향은 1이 연관관계 주인
  • 테이블 일대다에서는 항상 다(N) 쪽에 외래키가 있다.
  • 객체와 테이블의 차이 때문에 반대편 테이블의 외래 키를 관리하는 특이한 구조
  • @JoinColumn을 필수적으로 사용해줘야 한다. 사용하지 않으면 조인 테이블 방식(중간에 연결 테이블을 하나 추가하는 방식)을 사용한다.
    • JPA에서 자동적으로 Team_Member 중간 테이블을 생성
    • 중간에 테이블이 하나 더 생성 되면서, 성능 상에도 조금의 문제가 있고 아무래도 관리해줘야 하는 테이블이 하나 더 생기기 때문에 관리하는데 어려움이 있을 수 있다.

단점

  • 엔티티가 관리하는 외래 키가 다른 테이블에 존재

결론

  • 일대다 단방향 매핑 보다는 다대일 양방향 매핑을 사용하자.

일대다 양방향??

  • 공식적으로는 존재 하지 않지만, 약간의 꼼수를 통해 만들 수 있다.
  • @JoinColumn(insertable=false, updatable=false)사용
  • 읽기 전용 필드를 사용해서 양방향 처럼 사용하는 방법
  • 그냥 다대일 양방향을 쓰자.

REFERENCE

This post is licensed under CC BY 4.0 by the author.