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로 바꿔 새로운 객체가 아닌 상태로 변경해 준다
댓글
댓글 쓰기