티스토리 뷰
@OneToMany annotation 을 사용
Member 과 Member로 이루어진 Team 이 있을 때
Team이 1, Member가 N인 상태이다.
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import java.util.ArrayList;
import java.util.List;
@Entity
public class Team {
@Id
@GeneratedValue
@Column(name="TEAM_ID")
private Long id;
private String name;
@OneToMany
private List<Member> members;
public Team() {
members = new ArrayList<>();
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Member> getMembers() {
return members;
}
public void setMembers(List<Member> members) {
this.members = members;
}
}
import javax.persistence.*;
@Entity
public class Member {
@Id
@GeneratedValue
@Column
private Long id;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
@Column
private String username;
}
이 상태에서 아래의 main을 실행하게 되면
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("x");
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
try {
Member member = new Member();
member.setUsername("member 1");
em.persist(member);
Team team = new Team();
team.setName("TEAM A");
team.getMembers().add(member);
em.persist(team);
tx.commit();
} catch (Exception e) {
tx.rollback();
} finally {
em.close();
emf.close();
}
}
TEAM_MEMBER라는 다른 테이블을 하나 생성하게 된다.
Hibernate:
/* insert hellojpa.Member
*/ insert
into
Member
(username, id)
values
(?, ?)
Hibernate:
/* insert hellojpa.Team
*/ insert
into
Team
(name, TEAM_ID)
values
(?, ?)
Hibernate:
/* insert collection
row hellojpa.Team.members */ insert
into
Team_Member
(Team_TEAM_ID, members_id)
values
(?, ?)
과 같이 Team_Member가 생성되는 것을 볼 수 있다.
그렇기 때문에 @JoinColum을 사용하는 것이 좋다.
@OneToMany
@JoinColumn(name="TEAM_ID")
private List<Member> members;
members 에 JoinColumn을 붙여주자
Hibernate:
create table Team (
TEAM_ID bigint not null,
name varchar(255),
primary key (TEAM_ID)
)
Hibernate:
alter table Member
add constraint FKl7wsny760hjy6x19kqnduasbm
foreign key (TEAM_ID)
references Team
Hibernate:
call next value for hibernate_sequence
Hibernate:
call next value for hibernate_sequence
Hibernate:
/* insert hellojpa.Member
*/ insert
into
Member
(username, id)
values
(?, ?)
쿼리에 TEAM_Member 테이블이 없다. 그리고 Member에서 foreign key를 갖고있게 된다.
1인 Team 이 연관관계의 주인이다.
그 외에도 N쪽(member)에서 외래키를 가지고 있다.
객체와 테이블의 차이때문에 주인이 아니라 다른쪽에서 외래키를 관리한다.
1:N 단방향 매핑보다는 N:1 다대일 양방향 매핑을 사용하는 것이 좋다고 한다.
readOnly 의 특성(@JoinColumn(insertable = false, updatable = false))으로 Member 에 Team을 접근가능하게 해준다.
import javax.persistence.*;
@Entity
public class Member {
@Id
@GeneratedValue
@Column
private Long id;
public Long getId() {
return id;
}
@ManyToOne
@JoinColumn(insertable = false, updatable = false)
private Team team;
public void setId(Long id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
@Column
private String username;
}