[JPA] save 시 select 쿼리 발생 (Persistable 의 isNew 사용)
이전 포스팅에서 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