본문 바로가기
JPA

자바 ORM 표준 JPA 프로그래밍 - 기본키

by 임동무 2023. 3. 4.

1. 기본키

엔티티를 선언 할 때에는 기본키를 매핑해주어야 한다. 기본키란 Table 에서의 PK 를 의미하고

엔티티에서 기본키를 지정해주지 않으면

[ Entity does not have primary key ] 라는 오류를 발생시킨다.

- 엔티티 선언

@Entity
public class Team {

    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "TEAM_ID")
    private Long id;
    
    private String name;
}

 

여기서

[@Id]  어노테이션이 테이블에서의 기본키를 매핑해준다.

 

@Id 어노테이션만 사용하는 경우 -> 기본키를 직접 할당을 하겠다.

@GeneratedValue 어노테이션을 같이 사용하는 경우 -> 자동생성 전략을 사용하겠다.

라는 의미를 나타낸다.

 

2. 자동 생성 전략

자동생성 전략에는 총 4가지가 있다. 

1. strategy = GenerationType.TABLE

테이블 전략은 키 생성 전용 테이블을 하나 만들어서 시퀀스를 흉내내는 전략이다. 모든 DB에 적용이 가능하지만 성능에서 단점을 보인다.

이 전략을 사용하는 경우, DDL Auto 가 false 로 설정되어 있다면, 해당 시퀀스 테이블 생성을 먼저 해야한다. 

이는 테이블 생성 어노테이션인 @TableGenerator 와 함께 사용하여 해결할 수 있다.

 

 

2. strategy = GenerationType.IDENTITY

기본키 생성을 DB에게 위임하는 방식이다. 즉, DB에 저장될 때 DB 에서 PK 를 할당시켜주는 방법이다. 하지만 JPA 를 사용할 때 문제가 발생한다. 바로 영속성 컨텍스트에 저장될 때는 엔티티의 Id 값이 필요한데 PK 값이 없다는 것이다. 

이를 해결하기 위해 IDENTITY 전략을 사용하는 경우에는 flush() 가 이루어지는 시점이 아니라 영속성 컨텍스트에 저장하는 순간에 쿼리가 나간다. 즉, save() 메서드를 호출하는 시점에 insert 쿼리가 날라가고 Id 값을 받아오는 것이다.

 

 

3. strategy = GenerationType.SEQUENCE

SEQUENCE 전략은 persist 시에 DB 에 저장되어 있는 저장될 현재 시퀀스 정보를 next call 로 가져와서 현재 entity 할당해주는 방식이다. 그렇기 때문에 현재 시퀀스에 대한 정보가 필요하고 이는 호출할 때마다 조회해야하기 때문에 성능상에 이슈가 있다. 

이를 해결하기 위해서 allocationSize 옵션을 이용하면 DB 를 호출하지 않고 해당 개수 만큼을 미리 당겨와서 메모리에서 사용할 수 있다. 이는 Table 전략에서도 마찬가지이며 이를 통해 성능상의 이슈를 줄일 수 있다.

 

 

4. strategy = GenerationType.AUTO

이 전략은 DB 의 종류에 따라 3가지 중 전략 하나를 자동으로 선택한다.

다만 DDL Auto 가 false 로 되어있다면, DB 벤더에 따라 TABLE 혹은 SEQUENCE 전략을 사용하는 경우 sequence 나 key table 을 생성해야 하기 때문에 이를 주의해서 사용해야 한다.

 

 

 

댓글