"인프런 - 자바 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 |