본문 바로가기
JPA

JPA - 기본 키 매핑

by 왈레 2022. 4. 9.

기본 매핑 어노테이션

  • 직접할당 : @Id만 사용
  • 자동생성 : @GeneratedValue (네 가지 전략)
@Id @GeneratedValue(strategy = GenerationType.AUTO)
private Long id

 

자동생성 네 가지 전략

  1. IDENTITY : 기본 키 생성을 데이터베이스에 위임 (MySQL)
  2. SEQUENCE : 데이터베이스 시퀀스 오브젝트 사용 (Oracle), @SequenceGenerator 필요
  3. TABLE : 키 생성용 테이블 사용, (모든 DB에서 사용), @TableGenerator 필요
  4. AUTO : 방언에 따라 자동 지정 (기본 설정)

 

IDENTITY 전략

• 기본 키 생성을 데이터베이스에 위임

Insert id값을 null 값으로 세팅해야한다. (id 값을 넣으면 안됨)

id값을 수있는 시점은 값이 DB 들어갔을 때이다.

 

데이터가 영속성 컨텍스트에서 관리되려면 무저건 PK 있어야 한다.

IDENTITY 전략에서 데이터 생성 시 데이터가 DB 한번 들어가지 않으면 영속성 컨텍스트에서 관리가 없다.

 

JPA 보통 트랜잭션 커밋 시점에 INSERT SQL 실행하지만 이런 상황을 방지하기 위해서 기본키가 IDENTITY 전략이면 em.persist() 시점에 INSERT SQL 실행하고 바로 DB에서 식별자를 조회한다.

 

Member member = new Member();
em.persister(member);
System.out.println("member.id =" + member.getId());

//커밋을 하지않은 시점에도 member.id값이 있다는걸 확인할 수 있다.

 

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

 

 

SEQUENCE 전략

• @SequenceGenerator 필요

• 데이터베이스 시퀀스는 유일한 값을 순서대로 생성하는 특별한 데이터베이스 오브젝트이다. ex)오라클 시퀀스

• 주로 오라클, PostgreSQL, DB2, H2 데이터베이스에서 사용한다.

@SequenceGenerator 다음과 같이 @GeneratedValue 바로 사용해도 되지만 클래스에 해주는 것이 좋다.

 

SEQUENCE - @SequenceGenerator

allocationSize 기본값 = 50

 

SEQUENCE 전략과 최적화

SEQUENCE 전략은 데이터베이스 시퀀스를 통해 식별자를 조회하는 추가 작업이 필요하다.

따라서 데이터베이스와 2번 통신한다.

 

  1. 식별자를 구하기 위해 데이터베이스 시퀀스를 조회한다.
  2. 조회한 시퀀스를 기본 키 값으로 사용해 데이터베이스에 저장한다.

 

상세설명

em.persist(member) 호출하면 JPA 시퀀스 값을 얻기 위해 쿼리문(next call) DB 날린 시퀀스 값을 가져온후 데이터와 함께 1 캐시에 저장한다.

 

JPA는 시퀀스에 접근하는 횟수를 줄이기 위해 allocationSize를 사용한다.

간단히 설명하자면 여기에 설정한 값 만큼 한번에 시퀀스 값을 증가시키고 나서, 그만큼 메모리에 시퀀스 값을 할당한다.

예를들면 allocationSize가 50일때, 시퀀스를 한 번 조회 시 50을 증가시킨 다음에, 1~50 까지는 메모리에서 식별자를 할당한다. 그리고 51이 되면 시퀀스 값을 100으로 증가시킨 다음 51~100까지 메모리에서 식별자를 할당한다.

 

이 방법은 시퀀스 값을 선점하므로 여러 JVM에서 동시에 동작해도 기본 키 값이 충돌하지 않는다는 장점이 있다.

그러나 데이터베이스에 직접 접근해서 데이터를 등록할 때 시퀀스 값이 한번에 많이 증가하므로, 이런 상황이 부담스럽고 INSERT 성능이 중요하지 않다면 allocationSize를 1로 설정하고 사용하면 된다.

 

1번째 호출 : DB SEQ = 1   ||  어플리케이션 1 // 더미호출,  최초 SEQ -49

2번째 호출 : DB SEQ = 51  ||  어플리케이션 2

3번째 호출 : DB SEQ = 51  ||  어플리케이션 3

 

권장하는 식별자 전략

Long타입의 필드명은 Id로 IDENTITY, SEQUENCE 이 두 전략 중 하나를 사용하면 된다.

 

※ 출처 - 인프런 김영한 JPA

댓글