@GeneratedValue 전략

UkJJang·2021년 9월 10일
3

직접 기본키를 생성하는 방법

  • @Id 어노테이션 만을 사용하여 기본키를 직접 할당해주는 방법이 있다.

기본키를 자동으로 생성하는 방법 4가지

기본키를 자동으로 생성할 때에는 @Id와 @GenerratedValue 어노테이션이 함께 사용되어야 한다.

IDENTITY - @GeneratedValue(strategy = GenerationType.IDENTITY)

  • 기본키 생성을 데이터베이스에게 위임하는 방식으로 id값을 따로 할당하지 않아도 데이터베이스가 자동으로 AUTO_INCREMENT를 하여 기본키를 생성해준다.
	
    @Entity
    public class PkEx() {
		
        	@Id
        	@GeneratedValue(strategy = GenerationType.IDENTITY)
        	private Long id;
        
        	private String name;
            
        }
        

JPA는 보통 영속성 컨텍스트에서 객체를 관리하다가 commit이 호출되는 시점에 쿼리문을 실행하게 된다. 하지만 IDENTITY 전략에서는 EntityManager.persist()를 하는 시점에 Insert SQL을 실행하여 데이터베이스에서 식별자를 조회해온다.

그 이유는 영속성 컨텍스트는 1차 캐시에 PK와 객체를 가지고 관리를 하는데 기본키를 데이터베이스에게 위임햇기 때문에 EntityManager.persist()호출 하더라도 데이터베이스에 값을 넣기 전까지 기본키를 모르고 있기 때문에 관리가 되지 않기 때문이다.

따라서 특별한 경우로 IDENTITY 전략에서는 EntityManager.persist()를 하는 시점에 Insert SQL을 실행하여 데이터베이스에서 식별자를 조회하여 영속성 컨텍스트 1차 캐시에 값을 넣어주기 때문에 관리가 가능해진다.

SEQUENCE - @GeneratedValue(strategy = GenerationType.SEQUNCE)

  • 데이터 베이스의 Sequence Object를 사용하여 데이터베이스가 자동으로 기본키를 생성해준다.
  • @SequenceGenerator 어노테이션이 필요하다.
	
    @Entity
    @SequenceGenerator(
    	name = "USER_PK_GENERATOR",
        sequenceName = "USER_PK_SEQ",
        initailValue = 1,
        allocationSize = 50
        )
    public class PkEx() {
		
        	@Id
        	@GeneratedValue(strategy = GenerationType.SEQUENCE,
            			generator="USER_PK_GENERATOR")
        	private Long id;
        
        	private String name;
            
        }
        

SEQUENCE 전략도 IDENTITY 전략과 동일한 문제가 있다. 데이터베이스가 직접 기본키를 생성해 주기 때문이다.

EntityManager.persist() 가 호출 되기 전에 기본키를 가져와야 하므로 하이버네이트에서 hibernate: call next value for USER_PK_SEQ 을 실행하여 기본키를 가져온다.

그 후에 EntityManager.persist()호출하기 때문에 IDENTITY 전략과 다르게 쿼리문을 실행하지 않는다.

하지만 SEQUENCE 값을 계속 DB에서 가져와서 사용해야 하기 때문에 성능에 저하를 일으킬 수 있다 . 따라서 allocationSize 의 크기를 적당히 설정하여 성능 저하를 개선시킬 수 있다.

TABLE - @GeneratedValue(strategy = GenerationType.TABLE)

  • 키를 생성하는 테이블을 사용하는 방법으로 Sequence와 유사하다.
  • @TableGenerator 어노테이션이 필요하다.
	
    @Entity
    @TableGenerator(
    	name = "USER_PK_GENERATOR",
        table = "USER_PK_SEQ",
        pkColumnValue = "USER_SEQ",
        allocationSize = 1
        )
    public class PkEx() {
		
        	@Id
        	@GeneratedValue(strategy = GenerationType.SEQUENCE,
            			generator="USER_PK_GENERATOR")
        	private Long id;
        
        	private String name;
            
        }
        

TABLE 전략은 모든 데이터베이스에서 사용이 가능하지만 최적화 되어있지 않은 테이블을 사용하기 때문에 성능문제에 이슈가 있다.

AUTO - @GeneratedValue(strategy = GenerationType.AUTO)

  • 기본 설정 값으로 각 데이터베이스에 따라 기본키를 자동으로 생성한다.

기본키의 제약조건

  1. null이면 안된다.
  2. 유일하게 식별할 수 있어야한다.
  3. 변하지 않는 값이어야 한다.

권장하는 식별키 구성방법 : Long형 + 대체키 + 그에 맞는 적절한 키 생성전략 사용

profile
꾸준하게 성실하게

0개의 댓글