Today I Learned- Day3 [@DynamicInsert,@DynamicUpdate]

Sunghun Kim·2024년 11월 13일

Jpa

목록 보기
9/10

@DynamicInsert, @DynamicUpdate

@DynamicInsert와 @DynamicUpdate는 JPA에서 엔티티의 저장(insert) 및 업데이트(update) 시 엔티티의 변화가 있는 컬럼에 대해서만 SQL을 실행하고, 변화가 없는 컬럼에 대해서는 실행하지 않는 기능을 제공합니다.

한편, @DynamicInsert는 엔티티의 저장(insert) 시에만 동작하며, @DynamicUpdate는 엔티티의 업데이트(update) 시에만 동작합니다. 이를 사용하면 변화가 없는 컬럼의 SQL 실행을 줄일 수 있어서 성능 향상을 기대할 수 있습니다.

이 기능을 사용하지 않아도 JPA의 기본 동작에는 문제가 없으며, 실무에서는 개발자의 편의와 성능 최적화 측면에서 사용 여부를 결정하게 된다고 한다.

컬럼 하나의 값만 바꿨는데 모든 컬럼이 update 쿼리로 날라가는 것을 발견

@Transactional
  public void deleteUser(Long userId) {

    UserEntity user = userRepository.findById(userId).orElseThrow(
        () -> new CustomApiException(ResBasicCode.NULL_POINT, "User Not Found.")
    );
    
    // jpa entity 기본설정이라 모든 컬럼이 update 된다.
    user.setDeletionStatus(DeletionStatus.DELETED); 
    // Dirty Checking이 일어나는데 하나의 컬럼만 바꿨는데 전체가 다 바뀌는 쿼리다.. 이유가..?

  }

튜터님의 피드백!!

**@DynamicUpdate를 붙이지 않은 jpa Entity 기본설정일때의 쿼리

update p_user 
		set 
			address=?,
			deleted_at=?,
			deleted_by=?,
			deletion_status=?,
			email=?,
			manager_registration_status=?,
			nick_name=?,
			password=?,
			phone_number=?,
			role=?,
			updated_at=?,
			updated_by=?,
			user_name=? 
		where 
			id=?

💡@DynamicUpdate를 Entity에 붙였더니 내가 직접 set한 deletion_status EntityListener에서 set한 컬럼, Auditing 필드 updated_at만 바뀌는 것을 확인!!

Hibernate: 
    update p_user 
		    set
        deleted_at=?,
        deleted_by=?,
        deletion_status=?,
        updated_at=? 
    where
        id=?

@DynamicUpdate 어노테이션

사용하다 보면 엔티티의 업데이트가 예상치 못하게 전체 컬럼을 업데이트하는 상황을 마주칠 때가 있다.
특히 큰 테이블이나 자주 업데이트되는 테이블에서는 성능 문제가 생길 수 있다. 이럴 때 유용하게 사용할 수 있는 것이 바로 @DynamicUpdate 어노테이션이다.


@DynamicUpdate란?

@DynamicUpdate는 Hibernate에서 제공하는 어노테이션으로, 엔티티의 변경된 필드만 업데이트 한다. 기본적으로 Hibernate는 엔티티를 업데이트할 때 모든 컬럼을 업데이트하는 SQL을 생성한다.
하지만 @DynamicUpdate를 사용하면 실제 변경된 컬럼만 업데이트하는 SQL을 생성하도록 설정할 수 있다.

@DynamicUpdate 는 JPA 스펙이 아니고 Hibernate 기능이다. JPA 스펙으로는 변경되는 컬럼만 추적하는 기능이 없다.

@DynamicUpdate를 사용할 때의 장단점

@DynamicUpdate를 사용하면 업데이트 성능이 개선될 수 있지만, 항상 좋은 선택은 아니다. 그래서 장단점을 잘 이해하고 사용하는 게 중요하다.

장점

  1. 업데이트 성능 향상: 변경된 필드만 업데이트하므로 불필요한 업데이트를 줄일 수 있다.
  2. 트래픽 감소: 네트워크를 통해 전송되는 데이터 양이 줄어들어 트래픽을 줄일 수 있다.

단점

  1. SQL 캐시 사용 제한: 변경된 필드에 따라 동적으로 SQL을 생성하기 때문에 SQL 캐시를 효과적으로 사용할 수 없다.
  2. 복잡성 증가: 엔티티의 필드가 많이 변경되는 경우, 어떤 필드가 변경되었는지 추적하는 로직이 복잡해질 수 있다.

언제 사용하면 좋을까?

  • 테이블의 컬럼 수가 많고, 특정 컬럼만 자주 업데이트되는 경우
  • 대용량 트래픽을 처리해야 하는 경우

하지만 단순한 CRUD 애플리케이션에서는 @DynamicUpdate를 사용하는 것이 오히려 복잡성을 증가시킬 수 있으니, 꼭 필요한 경우에만 사용하는 것이 좋다.
이렇게 하면 불필요한 업데이트를 줄이고 성능을 최적화할 수 있을듯

Query메서드 깔끔하게 정렬하는 설정(application.yaml파일)

properties:
	hibernate:
      format_sql: true
      use_sql_comments: true
      default_batch_fetch_size: 500
profile
BackEnd Developer!!

0개의 댓글