🌱 SPRING/JPA

[JPA] 기본키 매핑 어노테이션

1HOON 2020. 7. 4. 14:00

 

기본키 매핑


엔티티 매핑 시 기본키가 되는 컬럼은 @Id 어노테이션을 붙여 지정할 수 있다. 

 

1
2
@Id
private Long id;
cs

 

그리고, 이 기본키 컬럼의 값을 JPA에서 자동으로 생성하게 할 수도 있는데, 만약에 기본키 값을 직접 할당할 경우에는 위 코드처럼 @Id 어노테이션만 사용하면 되고 자동 생성하게 할 경우 @GeneratedValue 어노테이션을 붙여주면 된다.

 

 

@GeneratedValue


1
2
3
@Id
@GeneratedValue
private Long id;
cs

 

@GeneratedValue 어노테이션을 붙이면, DBMS 종류에 따라 맞춰 자동적으로 값을 JPA에서 생성해 입력해준다. 이 어노테이션에는 strategy라는 옵션이 존재해 자동 생성 값을 어떻게 생성할지도 지정할 수 있다.

 

  • AUTO (기본값)
    • 지정된 Dialect에 따라 자동으로 지정해준다.
    • 1
      2
      3
      @Id
      @GeneratedValue(strategy = GenerationType.AUTO)
      private Long id;
      cs
  • IDENTITY
    • 기본키 값의 생성을 데이터베이스에 위임한다. → id 값을 null로 하면 알아서 DB에서 AUTO_INCREMENT 해준다.
    • MySQL, PostgreSQL 등
    • persist 메서드 호출 전까지 기본키 값을 생성하지 않고, persist 메서드가 수행되는 시점에 INSERT 쿼리를 수행한 뒤 값을 조회해 온다. 때문에, 객체가 DB에 저장된 이후에 기본키 값을 확인할 수 있다.
    • 때문에 기본키 값을 DB에 저장되기 전까지는 세팅할 수 없다.
    • 1
      2
      3
      @Id
      @GeneratedValue(strategy = GenerationType.IDENTITY)
      private Long id;
      cs
  • SEQUENCE
    • DB의 시퀀스 Object를 활용해 기본키 값을 지정하는 방식이다.
    • Oracle, PostgreSQL, DB2, H2 등
    • 1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      @Entity
      @SequenceGenerator(
                name = "TEMP_SEQ_GENERATOR"
              , sequenceName = "TEMP_SEQ"
              , initialValue = 1
              , allocationSize = 1)
      public class Temp 
      {    
          @Id
          @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "TEMP_SEQ_GENERATOR")
          private Long id;
      }
      cs
    • @SequenceGenerator 어노테이션의 sequenceName은 실제 DB에 존재하는 시퀀스 Object명이다.
    • IDENTIY와 마찬가지로, DB에 값이 저장된 이후에 id 값을 확인할 수 있다.
    • allocationSize를 50(기본값)으로 지정해 시퀀스를 50개를 미리 올려두고, 메모리에서 하나씩 사용하도록 하는 최적화 방식이 존재한다.
    • allcationSize가 크면 클수록 성능은 좋아지지만, 애플리케이션이 재구동되면 메모리에 올라가고 사용하지 않은 만큼의 시퀀스가 낭비되므로 적절하게 조정해야 한다.
  • TABLE
    • 키 생성 전용 테이블을 만들어 DB 시퀀스 Object를 흉내 내는 방식이다. 모든 데이터베이스에서 사용 가능하나, 성능은 좋지 않다.
    • 1
      2
      3
      4
      5
      6
      CREATE TABLE TEMP_SEQUENCE
      (
            SEQUENCE_NAME    VARCHAR(255)    NOT NULL
          , NEXT_VAL        BIGINT
          , PRIMARY KEY (SEQUENCE_NAME)
      )
      cs
    • 1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      @Entity
      @TableGenerator(
                name = "TEMP_SEQ_GENERATOR"
              , table = "TEMP_SEQUENCE"
              , pkColumnValue = "TEMP_SEQ"
              , allocationSize = 1)
      public class Temp 
      {    
          @Id
          @GeneratedValue(strategy = GenerationType.TABLE, generator = "TEMP_SEQ_GENERATOR")
          private Long id;
      }
      cs

 

 

권장하는 식별자 전략


기본키 제약조건은 NOT NULL이며, 유일해야 하고, 변하면 안 된다. 그러나, 먼 미래까지 생각했을 때 이 조건을 만족하는 자연키는 찾기 어렵다. 자연키 대신에 대체키를 사용하도록 하자.

 

  • 자연키 : 주민등록번호
  • 대체키 : 랜덤 값, UUID 등

 

그렇다면 권장하는 식별자 구성 방법은??

 

Long 형 + 대체키 + 키 생성 전략 → 맘 편하게 @GeneratedValue 어노테이션을 기본값(AUTO)으로 사용하자!

 

 


출처 :: 인프런 강의(자바 ORM 표준 JPA 프로그래밍 - 기본편)

반응형