-
[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