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 |