JPA Insert 시 Select 호출 되는 현상

JPA Entity @Id 필드값으로 DB 체번을 하지 않고 수동 입력으로 설정 해야 할 경우가 있다.

이때, 데이터 저장을 위해 save()를 호출해 보면, select가 먼저 실행 되고 insert가 실행 되는 것을 볼 수 있다. 간략히 이유를 설명하자면, id가 null 일때는 pk가 없는 것과 동일하기 때문에 entity manager는 새로운 데이터로 간주할 수 있으므로 바로 insert를 실행 한다. 그러나 id가 있으면 DB에 이미 존재하는 데이터 일 수 있으므로 먼저 찾아보고 없으면 insert를 하기 때문이다.

select가 없이 insert를 실행하고자 하면 아래와 같이 해당 entity에서 Persistable을 구현해 주면 된다.

@Entity
@Table(name = "my_table")
public class MyTable implements Persistable<String> {
    @Id
    @Column(name = "id")
    private String id;

    @Transient
    private boolean isNew = true;

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

    @Override
    public String getId() {
        return this.id;
    }

    @PrePersist
    @PostLoad
    void markNotNew() {
        this.isNew = false;
    }
    
    ...

}

다른 부분들은 제외하고 필요한 부분만 넣었고 설명을 추가하자면,

  • Persistable 인터페이스의 isNew()와 getId()를 구현해 주어야 한다
  • isNew()가 리턴할 상태값을 위해 isNew 필드를 만들고 DB에 저장되지 않게 @Transient를 붙여 준다
  • entity manager는 이 isNew()가 true이면 새로운 객체로 보고 insert 만 실행하게 된다
  • @PostLoad로 영속성 컨텍스에서 조회 되었거나 @PrePersist로 영속성 컨텍스에 저장 직전에 isNew를 false로 바꿔 새로운 객체가 아닌 상태로 변경해 준다


댓글

이 블로그의 인기 게시물

[Protocol] WIEGAND 통신

Orange for Oracle에서 한글 깨짐 해결책

[UI] GNB·LNB·SNB·FNB 용어 설명