-
[JPA] PK Mapping개발/Java 2023. 2. 12. 15:39
PK 매핑
@Id
를 통해서 기본키를 매핑한다.별도의 추가 어노테이션이 없다면 값을 직접 할당해야한다.
@GeneratedValue
를 통해서 값을 자동으로 할당해줄 수 있다.이 어노테이션에서 속성 값으로
strategy
를 설정해줄 수 있다.
IDENTITY 전략
GenerationType.IDENTITY
의 경우 DB에 생성을 위임한다.DB INSERT 시점에서 값을 설정한다. 즉, DB에 트랜잭션이 반영된 후에 ID 값을 알 수 있다.
하지만 영속성 컨텍스트에서 이를 관리하기 위해서는 PK 값이 존재해야 한다.
따라서,
commit
시점이 아닌persist
시점에 쿼리를 전달한다.JDBC 내부적으로 INSERT 시점에 반환 값을 확인할 수 있어 SELECT 쿼리가 발생하지는 않는다.
CREATE TABLE `table` ( `id` bigint generated by default as identity, `name` varchar(255) NOT NULL, PRIMARY KEY (id) ) INSERT INTO `table`(id, name) VALUES (null, ?); // -> id 값이 JPA 에서 NULL로 입력.
Sequence 전략
GenerationType.SEQUENCE
의 경우 DB에 생성을 위임한다.ORACLE의
SEQUENCE
와 같은 형태에 주로 적용된다./* HIBERNATE_SEQUENCE 객체를 생성해서 1부터 값을 증가시킴 */ CALL NEXT VALUE FOR HIBERNATE_SEQUENCE INSERT INTO table(id, name) VALUES (?, ?);
만일 테이블마다 다른 시퀀스를 쓰고싶다면?
시퀀스는 DB 시퀀스 객체에서 관리하기에
persist
시점에 DB에 접근해서 시퀀스 값을 가져온다.@SequenceGenerator
를 통해서 테이블마다 시퀀스를 정의하면 된다.
/* 시퀀스 제네레이터 생성 */ @SequenceGenerator(name = "member_seq_generator", // 제네레이터 명 sequenceName = "member_seq") public class Member { @Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "member_seq_generator") //시퀀스 제네레이터 지정 private Long id; ... }
Table 전략
테이블 매핑 전략을 사용하고 싶다면?
@TableGenerator
를 통해서 키 생성 전용 테이블을 생성하고 지정하면 된다.단, 성능 상의 단점이 있다.
/* 제네레이터 생성 */ @TableGenerator(name = "member_seq_generator", // 제네레이터 명 table = "my_sequences", //테이블 명 pkColumnValue = "member_seq") //pk 명 public class Member { @Id @GeneratedValue(strategy = GenerationType.TABLE, generator = "member_seq_generator") //제네레이터 지정 private Long id; ... }
매핑 전략의 단점과 성능 개선
시퀀스, 테이블 전략 모두 DB 접근을 통해야만 pk를 확인할 수 있다.
이에 대한 성능 하락을 개선할 수 있는 방법이 있다.
initialValue
와allocationSize
속성을 이용한다.allocationSize
는 기본 값이 50으로 이 사이즈 만큼 DB에 미리 할당한다.allocationSize
단위 만큼 메모리 상에서 관리하므로 그만큼 네트워크 부하가 줄게 된다.
PK 제약 조건
PK 제약 조건은
NOT NULL
, 변하지 않아야 하는 특성을 가진다.이를 만족시키는 키를 찾기가 어렵다.
따라서, 대체키와 키 생성 전략을를 추가적으로 함께 사용하는 것이 좋다.
'개발 > Java' 카테고리의 다른 글
[JPA] 양방향 연관관계 (1) 2023.04.18 [JPA] Persistence Context (0) 2023.01.14 [JPA] JPA (0) 2023.01.01 [Spring Boot] Reason: Validation failed for query for method public abstract (0) 2022.06.09 [SpringBoot] URL 이미지 반환하기(2) - Redis Caching (0) 2022.05.16