현의 개발 블로그

[엔티티 매핑] 기본 키 매핑 본문

스프링부트 이론/JPA

[엔티티 매핑] 기본 키 매핑

hyun2371 2023. 5. 10. 20:54

기본 키를 매핑하는 방법에는 직접 할당과 자동 생성이 있다.

직접 할당

기본 키로 지정하고 싶은 변수에 @Id를 추가한다.

id를 직접 대입한 후에 엔티티 매니저로 persist()하면 된다.

Member member = new Member();
member.setId("1");
em.persist(member);

자동 생성

자동 생성은 @Id와 @GeneratedValue를 추가하고 키 생성 옵션을 선택하면 된다.

옵션 설명
IDENTITY 기본 키 생성을 DB에 위임한다.
SEQUENCE DB 시퀀스를 사용해서 기본키를 할당한다.
TABLE 키 생성 테이블을 사용한다.
AUTO 선택한 DB에 따라 IDENTITY, SEQUNCE, TABLE 중에 자동 지정된다. (기본값)

 

IDENTITY

기본 키 생성을 데이터베이스에 위임한다.

주로 MySQL, PostgreSQL, SQL Server, DB2에서 사용한다.

ex: MySQL의 AUTO_INCREMENT

 

 

영속성 컨텍스트 1차 캐시에 저장되려면 id값을 알아야 한다.

AUTO_INCREMENT는 id 생성을 DB에 위임하므로, DB에 데이터를 삽입한 이후에야 id값을 알 수 있다.

이를 해결하기 위해 IDENTITY 전략에서는 예외적으로 쓰기 지연을 하지 않는다.

 

 

정리
JPA는 보통 commit() 시점에 insert SQL을 실행한다.
IDENTITY 전략은 예외적으로 em.persist() 시점에 insert SQL을 실행하고 DB에서 식별자를 조회한다.
(영속성 컨텍스트 1차 캐시에 저장하기 위해서)

 

 

 

SEQUENCE

DB 시퀀스를 사용해서 기본 키를 할당한다.

시퀀스를 지원하는 Oracle, PostgreSQL, DB2, H2 Database에서 사용할 수 있다.

시퀀스 오브젝트를 만들고, 시퀀스 오브젝트에서 값을 가져와서 기본 키를 설정한다.

 

따로 지정하지 않으면 하이버네이트가 생성한 기본 시퀀스를 사용한다

테이블마다 시퀀스를 따로 지정하고 싶으면, @SequenceGenerator를 매핑해 주면 된다.

 

@SequenceGenerator를 사용해서 "MEMBER_SEQ_GENERATOR" 라는 시퀀스 생성기를 만들었다.

시퀀스 이름은 "MEMBER_SEQ"로 설정하였다.

@Entity
@SequenceGenerator(
    name = "MEMBER_SEQ_GENERATOR",
    sequenceName = "MEMBER_SEQ",
    initialValue = 1, allocationSize = 50)
public class Member {
	@Id
 	@GeneratedValue(strategy = GenerationType.SEQUENCE,
    				generator = "MEMBER_SEQ_GENERATOR")
    private Long id;
 }

 

영속성 컨텍스트에 저장하기 위해 id가 필요하다.

persist()를 호출할 때, DB에서 먼저 시퀀스값을 불러와서 엔티티에 세팅한다.

SEQUENCE는 id 값을 미리 불러오기 때문에  IDENTITY와 달리 쓰기 지연이 가능하다.

 

 

 

시퀀스 값을 불러오기 위해 매번 네티워크를 왕복하면 성능이 나빠질 수 있다.

allocationSize 속성으로 미리 여러 개 가져와서 성능을 최적화할 수 있다.

해당 속성의 기본 값은 50으로, DB 시퀀스에서 미리 50개를 가져온다.

한 번 호출할 때 시퀀스 값을 50씩 증가시키고, 메모리에서는 1씩 사용한다.

 

TABLE

키 생성 전용 테이블을 하나 만들어서 데이터베이스 시퀀스를 흉내 내는 전략이다.

  • 장점: 모든 데이터베이스에 적용 가능하다
  • 단점: 성능 (테이블을 직접 사용하기 때문에 최적화가 되어 있지 않아서 락이 걸릴 수 있다)
create table MY_SEQUENCES (
  sequence_name varchar(255) not null,
  next_val bigint,
  primary key ( sequence_name )
)

 

식별자 생성기 이름을 MEMBER_SEQ_GENERATOR로 설정하였다.

테이블 이름과 pk 컬럼명을 각각 설정했다.

@Entity
@TableGenerator(
  name = "MEMBER_SEQ_GENERATOR",
  table = "MY_SEQUENCES",
  pkColumnValue = "MEMBER_SEQ", allocationSize = 1)
public class Member {
  @Id
  @GeneratedValue(strategy = GenerationType.TABLE,
  			generator = "MEMBER_SEQ_GENERATOR")
  private Long id;
}

AUTO

DB 방언에 따라  IDENTITY, SEQUENCE, TABLE 중 하나를 자동으로 선택한다.

 

 

권장하는 식별자 전략

기본 키 제약 조건: not null, 유일, 불변

변하면 안 되는 조건을 만족하는 자연키는 찾기 어렵다.

따라서 대리키(대체키)를 사용하는 게 바람직하다.

결론: Long형 + 대체키 + AUTO나 SEQUENCE 키 생성 전략을 사용하자.

 


Reference

 

자바 ORM 표준 JPA 프로그래밍 - 기본편 - 인프런 | 강의

JPA를 처음 접하거나, 실무에서 JPA를 사용하지만 기본 이론이 부족하신 분들이 JPA의 기본 이론을 탄탄하게 학습해서 초보자도 실무에서 자신있게 JPA를 사용할 수 있습니다., - 강의 소개 | 인프런

www.inflearn.com

Comments