테이블 마다 시퀀스 오브젝트를 따로 관리하고 싶으면 @SequenceGenerator에 sequenceName 속성을 추가한다.
@SequenceGenerator 필요
initialValue와 allocationSize 속성을 이용해 버퍼링 insert를 할 수 있다.
TABLE
@GeneratedValue(strategy = GenerationType.TABLE)
키 생성 전용 테이블을 하나 만들어서 키 생성을 한다.
@TableGenerator 필요
장점: 모든 데이터베이스에 적용 가능
단점: 최적화 되어있지 않은 테이블을 직접 사용하기 때문에 성능상의 이슈가 있음
DB들은 각자 기본키 생성에 최적화를 적용해놓았는데, 그걸 포기하게 되는 것
AUTO
@GeneratedValue(strategy = GenerationType.AUTO)
기본 설정 값
방언에 따라 위의 세 가지 전략을 자동으로 지정한다.
엔티티 매핑
연관관계 설정에서 고려해야할 객체와 테이블의 차이점은, 객체는 참조를 통해 연관관계를 맺고, 테이블은 외래키를 통해 연관관계를 맺는다는 것이다. 객체의 참조와 테이블의 외래키를 매핑하는 것이 이 챕터의 목표.
짚고 갈 용어
방향: 회원과 팀이 있을 때, 회원에서 팀으로, 혹은 팀에서 회원으로 한 쪽으로만 참조 가능한 것을 단방향이라고 한다. 반대로 양쪽이 서로 참조 가능한 것을 양방향이라고 한다.
다중성: RDB에서 흔히 얘기하는 일대일, 일대다, 다대다 등을 말한다.
연관관계의 주인: 객체를 양방향 연관관계로 만들면 연관관계의 주인을 설정해야한다.
단방향 연관관계
단방향 일대다 연관관계를 생각해보자. 객체와 테이블의 가장 큰 차이는 테이블은 외래 키 하나로 양방향 연관관계가 가능하지만 객체는 그렇지 않다는 점이다.
테이블은 A JOIN B가 가능하면 B JOIN A도 가능하다. 객체는 양방향으로 설정하려면 필드를 하나 더 추가해줘야한다. 즉 참조는 단방향이고, 조인은 양방향이다.
객체를 양방향으로 참조하려면 단방향 연관관계 2개를 만들어야한다.
@Entity
public class Member {
@Id
@Column(name = "MEMBER_ID")
private String id;
private String username;
@ManyToOne
@JoinColumn(name = "TEAM_ID")
private Team team;
public void setTeam(Team team) {
this.team = team;
}
...
}
@Entity
public class Team {
@Id
@Column(name = "TEAM_ID")
private String id;
private String name;
...
}
@ManyToOne: 이름 그대로 다대일 매핑이다. 한 회원은 하나의 팀에 속할 수 있고, 하나의 팀은 여러 회원을 가질 수 있다. 연관관계를 매핑할 때는 이렇게 다중성을 나타내는 어노테이션을 필수로 사용해야한다.
@JoinColumn(name = "TEAM_ID"): 조인 칼럼은 외래 키를 매핑할 때 사용한다. name 속성에는 매핑할 외래 키의 이름을 지정한다. 이 어노테이션은 생략할 수 있다.
연관관계 주인
만약 Team 객체에서 Member 객체를 참조하고 싶다면 팀->멤버 연관관계를 추가해주어야 한다.
@Entity
public class Team {
@Id
@Column(name = "TEAM_ID")
private String id;
private String name;
@OneToMany(mappedBy = "team")
private List<Member> members = new ArrayList<>();
...
}
사실 RDB 입장에서는 외래 키 하나로 양방향 참조가 가능하기 때문에 더이상의 정보가 필요 없다. 그러나 객체의 참조는 단방향으로만 가능하기 때문에
양방향 참조를 위해서는 단방향 참조 두 개가 필요하다. 외래 키는 하나인데 참조는 두 개이다. 이 차이 때문에 JPA는 두 객체 연관관계 중 하나를 정해서 테이블의 외래 키를 관리해야하는데 이를 연관관계 주인(Owner)이라고 한다.
연관관계 주인은 주인이 아닌 곳에 mappedBy 속성을 줌으로써 정할 수 있다. 오직 연관관계의 주인만이 데이터베이스 연관관계와 매핑되고 외래 키를 관리(등록, 수정, 삭제)할 수 있다.
mappedBy의 값으로는 주인 쪽에서 참조하는 이름을 넣어주면 된다. 이 경우에는 member가 주인이고 team을 참조하기 때문에 속성으로 "team"을 넣어주었다.
연관관계 주인은 항상 외래 키를 가지고 있는 테이블로 설정한다. ManyToX 관계에서 항상 Many 쪽이 외래 키를 가지므로 @ManyToOne에는 mappedBy 속성이 없다.
객체와 테이블, 필드와 칼럼 매핑
기본 키 생성 전략
IDENTITY
SEQUENCE
TABLE
AUTO
엔티티 매핑
연관관계 설정에서 고려해야할 객체와 테이블의 차이점은, 객체는 참조를 통해 연관관계를 맺고, 테이블은 외래키를 통해 연관관계를 맺는다는 것이다. 객체의 참조와 테이블의 외래키를 매핑하는 것이 이 챕터의 목표.
단방향 연관관계
단방향 일대다 연관관계를 생각해보자. 객체와 테이블의 가장 큰 차이는 테이블은 외래 키 하나로 양방향 연관관계가 가능하지만 객체는 그렇지 않다는 점이다.
테이블은
A JOIN B
가 가능하면B JOIN A
도 가능하다. 객체는 양방향으로 설정하려면 필드를 하나 더 추가해줘야한다. 즉 참조는 단방향이고, 조인은 양방향이다.객체를 양방향으로 참조하려면 단방향 연관관계 2개를 만들어야한다.
연관관계 주인
만약 Team 객체에서 Member 객체를 참조하고 싶다면 팀->멤버 연관관계를 추가해주어야 한다.
사실 RDB 입장에서는 외래 키 하나로 양방향 참조가 가능하기 때문에 더이상의 정보가 필요 없다. 그러나 객체의 참조는 단방향으로만 가능하기 때문에 양방향 참조를 위해서는 단방향 참조 두 개가 필요하다. 외래 키는 하나인데 참조는 두 개이다. 이 차이 때문에 JPA는 두 객체 연관관계 중 하나를 정해서 테이블의 외래 키를 관리해야하는데 이를 연관관계 주인(Owner)이라고 한다.
연관관계 주인은 주인이 아닌 곳에 mappedBy 속성을 줌으로써 정할 수 있다. 오직 연관관계의 주인만이 데이터베이스 연관관계와 매핑되고 외래 키를 관리(등록, 수정, 삭제)할 수 있다.
mappedBy의 값으로는 주인 쪽에서 참조하는 이름을 넣어주면 된다. 이 경우에는 member가 주인이고 team을 참조하기 때문에 속성으로 "team"을 넣어주었다.
연관관계 주인은 항상 외래 키를 가지고 있는 테이블로 설정한다. ManyToX 관계에서 항상 Many 쪽이 외래 키를 가지므로 @ManyToOne에는 mappedBy 속성이 없다.