본문 바로가기
SpringBoot

batch insert하기 Spring Data JPA saveAll() vs 네이티브 쿼리

by 오렌지마끼야또 2025. 4. 4.
728x90
반응형

 

 

 

두 방식의 가장 큰 차이는 영속성 컨텍스트 사용 유무(메모리)와 동작 방식.

 

 

Spring Data JPA에서 saveAll(Iterable<T>)은 내부적으로 하나하나 save()를 호출하는 구조.
for문 돌면서 persist(insert) 또는 merge(update)를 반복.

 

 

??? : saveAll 안쓰고 네이티브 쿼리 써도 @Transactional 을 쓰기 때문에 jdbc 버퍼에 저장되니까 메모리 쓰는건 똑같지않아?

 

 

List<MyEntity> list = createMillionEntities(); // 100만 개 생성
myRepository.saveAll(list);

 

saveAll()은 단순히 SQL만 실행하는 게 아니라 다음을 함
1. 엔티티 객체 생성
2. 모두 영속성 컨텍스트에 등록
3. 변경 여부 추적(더티 체킹)
flush 시점까지 메모리 안에 유지

 

MyEntity 100만 개가 영속성 컨텍스트(cache)에 남아 있어서 메모리 폭발 위험 있음(OutOfMemory).

 

또한!!

saveAll(Iterable<S> entities) 메서드는 내부적으로 각 엔티티가 새로 추가되는 것인지, 기존 데이터의 업데이트인지 판단하기위해 Hibernate는 각 엔티티의 상태를 확인하기 위한 SELECT 를 실행한다.

-> select 100만번, insert(update) 100만번이란 소리

 

 

 

네이티브 쿼리는?

EntityManager.createNativeQuery("INSERT INTO ...").executeUpdate()

 

단순히 SQL 문자열만!! JDBC 버퍼에 넣는 것뿐이고
Java 객체를 영속성 컨텍스트에 넣지도 않고, 상태 추적도 없음
insert SQL 한 줄만 있으면 끝나니까 메모리 훨씬 적게 사용

 

 

 

수천 건 이상이면 네이티브 쿼리 추천

 

 

728x90
반응형

댓글