본문 바로가기
개발/JPA

[JPA] 데이터를 insert 하기 전에 select하는 이유

by ynzu🤍 2021. 12. 2.
반응형

JPA를 이용하여 DB에 데이터를 insert하게 되면 id를 조건으로 select를 먼저 하고, insert를 하는 것을 확인할 수 있다.

(JPA는 조회 후 데이터가 존재한다면 update를 실행하고 존재하지 않으면 insert를 실행한다.)

 

대량 데이터를 처리하려다 보니 savaAll을 사용하게 되었는데,

xxxRepository.saveAll(entity);

1000건의 데이터를 한번에 등록하려면 select를 1000번 실행하는.....

JPA가 편리하긴 한데.. 이런 부분은.. 참 그렇다

 

그래서 save() 메소드가 어떻게 처리되고 있는지 살펴봤다.

@Transactional
public <S extends T> S save(S entity) {

	if (entityInformation.isNew(entity)) {
		em.persist(entity);
		return entity;
	} else {
		return em.merge(entity);
	}
}

새로운 entity면 persist() 메소드 아니면 merge() 메소드를 실행하는 것을 볼 수 있다.

새로운 entity 여부는 entity의 @Id값 유무에 따라 달라진다.. 본인이 저장하고자 하는 entity에는 항상 @Id값이 존재하므로 merge() 메소드가 실행되게 된 것이다.

(참고 : 식별자 생성전략이 @GenerateValue 경우 저장하는 시점에서는 식별자가 없어서 persist이 실행된다)

 

 
Entity 클래스에 Persistable를 implements하여 getId()와  isNew() 메소드를 재정의하면 insert전에 select하는 것을 막을 수 있다고 한다

본인은 id에 @GenerateValue를 설정할 수 없어 id값이 아닌 생성일자로 새로운 엔티티인지 판단하고자 했다.

아래는 그 예시이다!

@Entity
@ToString
@Table(name = "PRODUCT")
public class Product implements Persistable<String>{
	
    @Id
    @Column(name = "PRODUCT_ID", columnDefinition ="VARCHAR(36)")
    private String productId;
    
    //생략
    
	@CreatedDate
	@Column(name = "CREATE_DATE")
    private LocalDateTime createDate;
	
	@Override
    public String getId() {
        return id;
    }

    @Override
    public boolean isNew() {
        return createDate == null;
    }

}

@CreatedDate : Entity가 생성되어 저장될 때 날짜+시간이 자동 생성된다.

createDate의 데이터 존재 여부에 따라 새로운 엔티티인지 확인이 가능하다.

728x90
반응형

댓글