일대다 단방향은 일대다(1:N)에서 1(일)이 연관관계의 주인
일대다 관계에서 테이블을 보면 N(다)쪽에 외래 키가 있다.
객체와 테이블의 차이 때문에 반대편 테이블의 외래 키를 관리하는 특이한 구조
@JoinColumn
을 꼭 사용해야한다. 그렇지 않으면 조인 테이블 방식을 사용한다.
(중간에 테이블을 하나 추가)
Team 엔티티
@Entity
public class Team {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "TEAM_ID")
private Long id;
// 1에서 N을 참조한다.
@OneToMany
@JoinColumn(name = "TEAM_ID")
private List<Member> members = new ArrayList<>();
}
JpaMain
public class JpaMain {
public static void main(String[] args) {
Member member = new Member();
member.setUsername("member1");
em.persist(member);
Team team = new Team();
team.setName("teamA");
//
team.getMembers().add(member);
//
em.persist(team);
tx.commit();
}
}
Hibernate:
/* insert hellojpa.Member
*/ insert
into
Member
(USERNAME, MEMBER_ID)
values
(?, ?)
Hibernate:
/* insert hellojpa.Team
*/ insert
into
Team
(name, TEAM_ID)
values
(?, ?)
commit()
시점에 insert 쿼리가 나가는 것은 당연하다.
하지만 일대다 관계에서는 추가적으로 쿼리가 발생한다.
Hibernate:
/* create one-to-many row hellojpa.Team.members */ update
Member
set
TEAM_ID=?
where
MEMBER_ID=?
DB에서 외래키는 MEMBER
테이블에서 관리가 되고 있기 때문에, 추가적으로 별도의 쿼리가 나가는 것이다.
일대다 단방향 매핑의 단점
일대다 단방향 매핑보다는 다대일 양방향 매핑을 사용하자
일대다 단방향의 코드 + Member 엔티티에 @JoinColumn
어노테이션을 추가해줘야 한다.
@Entity
public class Member {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
@ManyToOne
// 양방향 참조를 억지로 만들면서 읽기 전용으로 강제한다.
@JoinColumn(name = "TEAM_ID", insertable = false, updateble = false)
private Team team;
}
이런 매핑은 공식적으로 존재하지 않는다.
@JoinColumn(insertable=false, updatable=false)
읽기 전용 필드를 사용해서 양방향 처럼 사용하는 방법
다대일 양방향을 사용하자
참고 :
김영한. 『자바 ORM 표준 JPA 프로그래밍』. 에이콘, 2015.