JPA는 기본적으로 1차 캐시에 @Id로 키를 가지고 @Entity로 값을 가진다. 

 

그렇기에 1차 캐시에 엔티티를 저장하려면 @Id의 값이 필수적인데, @GeneratedValue는 자동으로 이 id값을 생성해준다.

 

@GeneratedValue

GenerationType.IDENTITY:

  • id값(기본 키)을 DB에서 생성한다.
  • JPA는 기본적으로 트랜잭션이 끝난 직후 데이터가 DB에 반영되지만, IDENTITY인 경우에는 엔티티를 영속시킬 때 쿼리가 DB에 반영된다.

GenerationType.IDENTITY은 왜 엔티티가 영속될때 쿼리가 DB에 반영되는가?

  • IDENTITY는 DB에서 id값을 넘겨받는다. 즉, DB에 넘어가기 전 까지는 id값이 존재하지 않는다.
  • JPA의 1차 캐시는 id값을 가지고 있어야 저장할수 있으므로, DB에 id값을 받아지 않는 한 저장할 수 없다.
  • 그렇기 때문에 JPA에서 IDENTITY 설정을 사용 할 경우에 영속화를 하는 시점에 미리 쿼리를 날려서 id를 조회하여 1차 캐시에 엔티티를 저장한다. 

GenerationType.SEQUENCE:

  • DB에서 id값을 가져오지만 IDENTITY와 다르게 다량으로 id값을 가져올 수 있다.
  • 차이점은 IDENTITY와 다르게 영속을 하더라도 트랜잭션이 끝난 시점에 DB에 반영된다.
  • @SequenceGenerator 로 시퀀스를 따로 설정할 수 있다.(따로 설정하지 않을 시 hibernate_sequence의 값을 사용한다)

GenerationType.SEQUENCE는 어떻게 IDENTITY와 다른가?

  •  @SequenceGenerator의 속성 중, allocationSize 라는 속성은 DB에서 sequence값을 한번에 몇개씩 가져올지를 정한다.
  • 이 allocationSize의 기본값은 50인데,  1부터 51까지의 시퀀스값을 db에서 생성하여 미리 JPA에 가져와서 어플리케이션이 종료될 때 까지 가져온다는 의미다.
  • 이렇게 가져온 시퀀스 값을 엔티티를 영속할 때 마다 하나씩 부여하여 1차 캐시에 저장할 수 있다. 
  • 동시성 이슈없이 다양한 문제들을 해결 할 수 있다고 한다.

GenerationType.TABLE

  • DB의 시퀀스를 흉내내는 키 전용 생성 테이블을 생성한다.
  • 실제 운영에서 사용하기에는 기존의 DB 생성 규칙과 다를 수 있으므로 쓰기가 어렵다.
  • 모든 DB에 적용할 수 있다는 장점이 있지만, 보통은 테이블 전략을 잘 사용 하지 않는다고 한다.

결론

전략은 SEQUENCE를 사용하자

'Java > JPA' 카테고리의 다른 글

JPA - 상속관계 매핑, @MappedSuperclass  (0) 2023.10.04
JPA - 연관관계  (0) 2023.10.01
JPA - 플러시, 준영속 상태  (0) 2023.09.20
JPA - 영속성컨텍스트(2)  (0) 2023.09.20
JPA - 영속성 컨텍스트(1)  (0) 2023.09.18

+ Recent posts