데이터 목록을 불러와 JPA로 업데이트를 시킬 때, 변경되지 않은 컬럼도 update 쿼리에 포함된다.
Hibernate: update lecture set class_div=?, class_nm=?, class_type=?, credit=?, day_night_nm=?, etc_permit_yn=?, prof_nm=?, sec_permit_yn=?, shyr=?, sub_dept=?, subject_div=?, subject_div2=?, subject_nm=?, subject_no=?, term=?, tlsn_count=?, tlsn_limit_count=?, used=?, year=? where id=?
Hibernate: update lecture set class_div=?, class_nm=?, class_type=?, credit=?, day_night_nm=?, etc_permit_yn=?, prof_nm=?, sec_permit_yn=?, shyr=?, sub_dept=?, subject_div=?, subject_div2=?, subject_nm=?, subject_no=?, term=?, tlsn_count=?, tlsn_limit_count=?, used=?, year=? where id=?
변경된 데이터를 비교해 업데이트 시키려고 할 때, 이렇게 모든 컬럼을 업데이트시키는 것을 볼 수 있다.
여러 컬럼 중 변경될 컬럼이 일부라면, @DynamicUpdate
어노테이션을 사용하여 업데이트 된 컬럼만 변경하도록 할 수 있다.
이 어노테이션은 동적 수정 쿼리를 생성한다.
DynamicUpdate
를 사용하려면 Entity 클래스에 어노테이션만 붙여주면 된다.
@Entity
@DynamicUpdate
public class Lecture {
@Id
private int id;
@Column
private String subject_nm;
@Column
private String class_div;
@Column
private Integer tlsn_count;
@Column
private boolean used;
...
}
이후 업데이트를 실행해보면 다음과 같이 변경된 컬럼만 업데이트되는 모습을 확인할 수 있다.
Hibernate: update lecture set tlsn_count=? where id=?
Hibernate: update lecture set used=? where id=?
원래 Hibernate는 애플리케이션을 처음 로드할 때, 성능 향상을 위해 entity를 모두 스캔하여 업데이트할 쿼리를 캐시해놓고 사용한다.
반면, DynamicUpdate
를 사용하면 캐싱을 하지 않고 그때그때 변경된 컬럼에 맞는 새로운 동적 쿼리를 만든다.
이는 DynamicUpdate
를 사용함에 있어서 performance overhead가 발생하여 성능상 손해가 있다는 것이다.
그래서 무작정 이 어노테이션을 사용하기보다는, 상황에 맞게 사용하는 것이 필요하다.예를 들어, 테이블에 컬럼이 많고, 이 컬럼 중에서 일부 컬럼만 자주 바뀌는 경우 사용하는 것이 좋다.
이외에도 @Version
을 사용하지 않는 낙관적 락(Optimistic lock)을 사용할 때는 어떤 것이 dirty field(변경된 필드)인지 체크해서 where 조건을 만들어야 하기 때문에 @DynamicUpdate
를 사용해야 한다.