본문 바로가기
IT/Java

[JPA] save 시 select 쿼리 발생 (Persistable 의 isNew 사용)

by 성준하이 2024. 2. 7.
반응형

이전 포스팅에서 dirty checking 관련해서 글을 다룬적이 있다.

자세한 내용은 아래 참고 포스팅을 참고 바란다.

 

엔티티를 가지고 작업을 하게 될 경우 매번 select 을 하고 update를 하거나 insert 를 할때 더티 체킹을 한다면

 

만약 bulk insert를 jpa에서 하게 될 경우엔 어떻게 해야할까?

 

별도의 작업이 없이 읽어서 insert를 하기만 하면된다.


코드는 아래와 같이 간단하다.

TestTable ent = TestTable.builder()
.id(id)
.nameValue("test")
.gender(1)
.build();
repo.save(ent);

 

이대로 실행을 하면 

[interceptor] requestURI : /test/entitysetnew
Hibernate: 
    select
        t1_0.id,
        t1_0.gender,
        t1_0.name_value 
    from
        test_table t1_0 
    where
        t1_0.id=?
Hibernate: 
    insert 
    into
        test_table
        (gender, name_value, id) 
    values
        (?, ?, ?)

이렇게 출력이 된다.

 

즉 select를 하고 id 기준에 값이 테이블에 없으니 insert를 해주는것이다.

만약 있었다면 update가 날라갔을 것이다.

 

하지만 이 id가 테이블에 값이 있는지 없는지 모를때는 이런 방식이 좋지만,

새롭게 bulk insert를 할 경우엔 불필요하게 select 작업이 진행이 된다.

 

이럴 경우엔 setNew 를 통해서 컬럼을 변경해주면 된다.

 

entity에

public class TestTable implements Persistable<String> {
...

이런식으로 

Persistable 를 상속 받고,

그 안에 들어가보면 isNew 라는 항목이 있다.

save 처리 로직 

save함수는 아래와 같이 흘러간다.

@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);
     }
}

is New 라는 값이 true면 insert 이다.

 

그럼 isNew 값을 강제로 true 로 셋팅해주면 된다.

 

public class TestTable implements Persistable<String> {

...
...
     @Override
     public boolean isNew() {
          return true;
     }
}

 

이렇게 설정하고 로그를 보면 select가 없이 insert 가 되는걸 볼수 있다.


참고 포스팅

https://thenicesj.tistory.com/411

 

JPA 더티체킹(Dirty Checking) 이란?

JPA에 대해서는 아래 참고 포스팅을 참고하면 확인해 볼 수 있다. 이번 포스팅에서 다뤄볼 내용은 더티체킹이라는 개념이며 직역으로는 변경상태 감지라고 느낄 수 있다. JPA에서는 값을 데이터

thenicesj.tistory.com

 

반응형

댓글