JPA Entity ID 전략을 IDENGITY로 사용하고 있을 때, JPARepository를 이용한 saveAll() 호출 시 bulk Insert를 기대했지만 그렇지 않았다.

그 이유는 무엇일까?

벌크 Insert 란?

벌크(Batch) Insert는 대량의 데이터를 한번의 쿼리로 삽입시키는 방식이다.

즉, 개별적인 Insert 문을 사용하는 것이 아니라 아래와 같이 하나의 SQL 문만 사용한다.

INSERT INFO table (col1, col2) VALUES 
(val11, val12),
(val21, val22),
(val31, val32);

개별 Insert일 경우 한 트랜잭션 내에서 Insert 개수 만큼 DB와 네트워크 통신이 발생하므로 지연 시간이 증가할 것이다.

따라서, 여러 데이터를 하나의 쿼리로 처리한다면 성능이 향상된다.


SaveAll()과 Save()의 동작방식

saveAll()은 내부적으로 save()를 사용 하므로, 동작방식은 동일하다.

Untitled

Untitled

saveAll()를 호출하면 엔티티 개수 만큼 save()를 호출한다.

즉, 한 트랜잭셔 내에서 10개의 엔티티를 저장할 때, saveAll()를 한번 호출하던, save()를 10번 호출하던 같은 결과가 나타난다.

💡 그럼 Insert 문이 발생하는 시점은 언제일까?

Untitled

AbstractEntityInformation.isNew() 를 보게 되면, 영속성 컨텍스트에서 엔티티의 ID를 가져오고 해당 ID가 null(0L)인지 판별하여 새로운 엔티티 객체임을 판단한다. 만약, 새로운 객체일 경우 persist()를 통해 영속화를 진행한다.