본문 바로가기
  • 개발공부 및 일상적인 내용을 작성하는 블로그 입니다.
JPA

기본 키 매핑 - 1

by 방구석 취준생 2020. 9. 21.

"인프런 - 자바 ORM 표준 JPA 프로그래밍 강의를 듣고 작성한 글 입니다."

www.inflearn.com/course/ORM-JPA-Basic#

 

자바 ORM 표준 JPA 프로그래밍 - 기본편 - 인프런

JPA를 처음 접하거나, 실무에서 JPA를 사용하지만 기본 이론이 부족하신 분들이 JPA의 기본 이론을 탄탄하게 학습해서 초보자도 실무에서 자신있게 JPA를 사용할 수 있습니다. 초급 웹 개발 프로그

www.inflearn.com

 

- 기본 키 매핑 어노테이션

두 가지 어노테이션이 사용 가능하다.

- @Id

- @GeneratedValue

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;

 

@Id 어노테이션

: 기본 키 값을 직접 할당할 경우 사용한다.

->

@Id

private String id;

위와 같이 코드를 작성하였을 때 JPA 구현 클래스에서 id 값을 Setter 메소드를 통해 insert 했을 경우 hibernate 에서 작성해주는 SQL 은 다음과 같다.

Hibernate: 
    
    create table Member (
       id varchar(255) not null,
        name varchar(255),
        primary key (id) // 기본 키로 지정
    )

그런데 보통 관계형 데이터베이스를 사용하면 위의 경우와 같이 직접 id 값을 삽입하는것이 아니라, Oracle 의 경우 Sequence(DB가 자동으로 숫자값을 generate 해주는 것), Mysql 의 경우 AutoIncrement(값을 null 로 지정해주면 DB 가 알아서 값을 순차적으로 증가하게 세팅 해주는 것)과 같이 값을 자동으로 할당해주는 방식을 사용할 수 있다.

 

 

@GeneratedValue 어노테이션

- @GeneratedValue(strategy = GenerationType.AUTO) // AUTO 가 기본 default 값이다.

: 값을 직접 할당하는게 아니라 DB 방언에 맞춰서 자동으로 키 값을 생성해주는 것이다.(IDENTITY, TABLE, SEQUENCE 중에서 방언에 맞게 자동으로 설정해준다.) (즉, 사용하는 DB 에 따라 자동으로 해당 DB에서 지원하는 전략으로 설정해 준다는 것)

 

 

기본키 매핑 전략(1) - IDENTITY 전략

- @GeneratedValue(strategy = GenerationType.IDENTITY)

: 기본 키 생성을 데이터베이스에 위임한다.(예시 : Mysql 의 AutoIncrement)

 

기본키 매핑 전략을 IDENTITY 로 설정했을 경우 코드 및 hibernate SQL

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
Hibernate: 
    
    create table Member (
       id varchar(255) generated by default as identity,
        name varchar(255),
        primary key (id)
    )

 

위와 같이 H2 방언에 맞춰서 생성된 데이터베이스는 기본 키 값이 1 부터 시작하여 자동으로 생성된다.

또한 이후에 들어오는 entity 는 기본 키 값이 1씩 증가하여 들어오게 된다.

Hibernate: 
    /* insert hellojpa.Member
        */ insert 
        into
            Member
            (id, name) 
        values
            (null, ?) // hibernate sql 에서는 id 값이 null 로 들어가는 것을 확인할 수 있다.

 

참고로 여기서 persistence.xml 파일에서 DB 방언을 H2 가 아닌 Mysql 로 바꿀 시 다음과 같은 hibernate SQL 이 생성된다.

Hibernate: 
    
    create table Member (
       id varchar(255) not null auto_increment, // 다음과 같이 Mysql 에 맞는 방언으로 기본 키가 자동으로 설정된다.
        name varchar(255),
        primary key (id)
    ) engine=MyISAM

 

* IDENTITY 전략의 특징

- IDENTITY 전략은 id 에 값을 넣는 것 없이 DB에 entity 를 insert 해야 한다. 이를 통해 DB에서 insert 로 id 값이 null 값으로 들어오면 그때 DB 에서 값을 세팅해준다.

- 여기서 문제가 될 수 있는 것은 바로 트랜잭션 내부에서 entity 와 관련된 처리를 위해 영속성 컨텍스트의 관리를 받아야 하는데 그러려면 무조건 기본 키 값이 있어야 하나 IDENTITY 전략은 entity 가 DB에 들어가봐야 알 수 있다는 것이다.

- 기본 키가 없으니 JPA 를 통해 데이터베이스에 넣을 방법이 없게 되는 제약이 발생한다.

 

** 해법

- IDENTITY 전략에서만 예외적으로 persist 메소드를 호출하는 시점(영속성 컨텍스트에 entity 를 올리는 시점)에 데이터베이스 insert 쿼리가 전달되게 된다.

(원래는 트랜잭션 커밋 시점에 쿼리가 전달된다.)

- 이후 데이터베이스에서 매핑 된 기본 키 값을 JPA 가 내부적으로 select 해서 가져오게 되는데, 이렇게 가져온 기본 키 값을 영속성 컨텍스트로 가져와서 JPA 가 해당 entity 를 관리하게 된다.

- 따라서 쓰기 지연 SQL 저장소와 같이 쿼리들을 모아서 entity 를 insert 하는게 불가능하다는 단점이 있다.(즉, 버퍼링 기능을 이용할 수 없다.)

'JPA' 카테고리의 다른 글

기본 키 매핑 - 3  (0) 2020.09.21
기본 키 매핑 - 2  (0) 2020.09.21
필드와 컬럼 매핑 - 2  (0) 2020.09.19
필드와 컬럼 매핑 - 1  (0) 2020.09.19
객체와 테이블 간 Entity 매핑  (0) 2020.09.19