JpaRepository.save 동작방식은 persist 하거나 merge를 한다.
@Transactional
@Override
public <S extends T> S save(S entity) {
Assert.notNull(entity, "Entity must not be null.");
if (entityInformation.isNew(entity)) {
em.persist(entity);
return entity;
} else {
return em.merge(entity);
}
}
}
- 엔티티에 Id 값이 있으면 DB를 조회 (select)한 후에 insert 하게 된다.
생성전략이 존재하지 않을 경우 merge 로 동작.
- merge 는 입력받은 entity 를 복사한 후 진행하기에 리소스 소모가 있다.
생성전략이 존재하는 경우 persist 로 동작한다.
ID 생성 전략이 없고 애플리케이션에서 Set하는 방식
애플리케이션에서 ID 를 생성해줬기에 DB 에 값이 있나 확인하기 위해 select 를 날려본 후에, INSERT 가 이루어진다.
- 즉, merge 방식으로 동작
ID 생성 전략이 존재할 때
GenerationType.IDENTITY
- IDENTITY 는 id 값을 세팅하지 않고, insert 쿼리를 날리면 database 시스템에서 자동으로 가져와 엔티티에 지정한다.
- id 값 생성에 대해서 database 에서 관여하기에 save 메소드를 수행시 persist 로 동작한다.
- select 하지 않고 바로 insert 1번을 날린다
GenerationType.SEQUENCE
- database 의 sequence 기능을 사용하는 기능
- persist 를 호출하면 (spring data jpa 의 경우 save) sequence 를 가져온다.
- 가져온 Sequence 를 id 에 할당하고 (영속성 상태), transaction 이 commit 될 때, insert 쿼리를 날린다.
GenerationType.Table
- 키 생성 전용 테이블을 만들어서 시퀀스처럼 동작하게 하는 방식.
- 모든 데이터베이스에서 사용할 수 있지만 문제점이 있다.
- Sequence 나 Identity 방식은 하나의 Request 로 처리가 가능하지만 테이블 생성전략은 3개의 step이 필요하다
- lock 을 잡고, seq 를 증가시키고 데이터베이스에 저장한다. (리소스 소모)
- 그렇기에 운영할 때 잘 사용하지 않는다.
참조
'Spring > JPA' 카테고리의 다른 글
QueryDSL 설정 - SpringBoot 2.7.X & SpringBoot 3.x 버전 (0) | 2023.01.18 |
---|---|
Jpa Insert, update delete 시 select query를 통한 먼저 조회하지 않는 방법.md (1) | 2023.01.18 |
JPA Hibernate Id 생성 전략과 UUID 전략 (0) | 2023.01.18 |
Jpa Hibernate Custom Id Generator (1) | 2023.01.18 |
Jpa ArrayType. PostgreSQL Array Type을 저장하는 방법 - Hibernate Types, List, Array (0) | 2023.01.05 |