✏️ [JPA] @DynamicUpdate

박상민·2024년 1월 1일
0

JPA

목록 보기
23/24
post-thumbnail

Hibernate와 함께 Spring Data JPA를 사용하면 Hibernate의 추가 기능도 사용할 수 있다.
@DynamicUpdte는 그러한 기능 중 하나이다.

⭐️ 개요

@DynamicUpdate는 JPA Entity에 사용하는 어노테이션인데, 실제 값이 변경된 컬럼ㅁ만으로 update 쿼리를 만드는 기능이다.

Spring Data JPA를 사용해서 개발을 하다보면 수정 부분에서 변경되지 않은 컬럼도 update 쿼리에 포함하는데 큰 영향이 없어보이지만 쿼리 수가 많아질수록 차이가 발생한다.

📌 사용 예시

Comment

@Entity
class Comment(
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String body;
    
    private Int likeCount;
    
    private LocalDateTime createTime;
)

CommentRepository

interface CommentRepository : JpaRepository<Comment, Long> { }

Test

@Test
@Transactional
@Rollback(false)
public void update 결과 로그() {
    Comment comment = commentRepository.findByIdOrNull(1)
        ?: throw EntityNotFoundException()

    comment.likeCount = comment.likeCount + 1
}

실행결과

Hibernate: select comment0_.id as id1_1_0_, comment0_.article_id as article_5_1_0_, comment0_.body as body2_1_0_, comment0_.created_at as created_3_1_0_, comment0_.like_count as like_cou4_1_0_, article1_.id as id1_0_1_, article1_.body as body2_0_1_ from comment comment0_ left outer join article article1_ on comment0_.article_id=article1_.id where comment0_.id=?
Hibernate: update comment set article_id=?, body=?, created_at=?, like_count=? where id=?

실행 결과를 보면 likeCount의 값만 변경을 했음에도 불구하고, set 절 안에 body와 createdAt도 새로 변경값을 넣어주고 있는것을 알 수 있다.

자 이제 Comment에 @DynamicUpdate를 추가해서 다시 실행해보자.
Comment

@Entity
@DynamicUpdate
class Comment(
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String body;
    
    private Int likeCount;
    
    private LocalDateTime createTime;
)

실행 결과

Hibernate: select comment0_.id as id1_1_0_, comment0_.article_id as article_5_1_0_, comment0_.body as body2_1_0_, comment0_.created_at as created_3_1_0_, comment0_.like_count as like_cou4_1_0_, article1_.id as id1_0_1_, article1_.body as body2_0_1_ from comment comment0_ left outer join article article1_ on comment0_.article_id=article1_.id where comment0_.id=?
Hibernate: update comment set like_count=? where id=?

update 쿼리의 set부분에 실제로 변경한 like_count만 설정이 추가되었음을 알 수 있다.

📌 결론

@DynamicUpdate는 변경된 컬럼만 찾아서 업데이트를 진행한다.

  • 변경된 컬럼만 찾는다.
  • 변경되는 컬럼에따라 쿼리가 변경된다.

언제 사용해야 좋을까?
공식 문서에는 '하나의 테이블에 정말 많은 수의 컬럼이 있는데, 몇몇개의 컬럼만 자주 업데이트 하는 경우에 사용하라'고 되어있다.

아니면 @Version을 사용하지 않는 Optimistic Locking의 경우에 사용하라고 되어있다.
(Version을 사용하지 않고, 모든 필드를 Optimistic locking의 조건으로 걸게되면 어떤게 dirty 필드인지 체크해서 where조건을 만들 필요가 있기 때문)


출처
https://www.baeldung.com/spring-data-jpa-dynamicupdate
https://velog.io/@freddiey/JPA%EC%9D%98-DynamicUpdate
https://hyune-c.tistory.com/entry/DynamicUpdate-%ED%99%9C%EC%9A%A9%EA%B8%B0

profile
스프링 백엔드를 공부중인 대학생입니다!

0개의 댓글