• 티스토리 홈
starryeye
  • 프로필사진
    starryeye
    • 분류 전체보기 (189)
      • C++ (17)
      • Java (24)
      • OOP (5)
      • Spring Reactive Stack (12)
        • Reactive Streams (3)
        • Netty (4)
        • Reactor (1)
        • Webflux (3)
        • DB, Cache 연동 (1)
      • Spring (90)
        • Core (17)
        • MVC (33)
        • Client (2)
        • Security (4)
        • DB, Cache 연동 (33)
      • DataBase (12)
        • RDBMS (2)
        • NoSQL (10)
      • Message Broker (6)
      • Web (4)
      • Network (4)
      • 대규모 시스템 설계 (15)
  • 방문자 수
    • 전체:
    • 오늘:
    • 어제:
  • 최근 댓글
      등록된 댓글이 없습니다.
    • 최근 공지
        등록된 공지가 없습니다.
      # Home
      # 공지사항
      #
      # 태그
      # 검색결과
      # 방명록
      • JPA Merge, Dirty Check
        2023년 06월 06일
        • starryeye
        • 작성자
        • 2023.06.06.:52
        반응형

        이번 포스트에서 다룰 주제는 JPA 의 Merge, Dirty Check 에 대해서이다.
         
        merge() 에 대해서 데이터 업데이트 용도로 쓰면 위험하므로 권장하지 않는 방법이다.
         
        왜 이런말이 나왔을까..

        위 코드는 Spring Data Jpa 의 SimpleJpaRepository 의 Save 메서드 정의 부분이다.
         
        Jpa 를 잘 모르고 사용하면..
        데이터 업데이트를 위해서 비/준영속 상태의 엔티티로
        save 를 호출해버린다면 merge 를 호출한 상황이 발생하기 때문이다.
         
         
        참고>
        isNew() 에 대해서.. 알아보자
        JPA 식별자 생성 전략이 @GenerateValue 이면, save() 호출 시점에 식별자가 없으므로
        새로운 엔티티로 인식해서 persist() 로 로직이 흘러간다..
         
        하지만..
        JPA 식별자를 Application layer 에서 만들어주는 형태이면..
        save() 호출 시점에 식별자가 존재해버리므로.. merge() 가 동작해버린다.
        merge() 는 DB 에 해당 식별자가 존재하는지 확인하는 쿼리를 날리고
        식별자가 없으면 새로운 엔티티로 인지한다. (매우 비효율적)
        따라서, PK 직접 할당 방식을 채택 할 경우에는..
        Persistable 인터페이스를 Entity 가 상속받도록 하여 isNew() 메서드를 재정의 하는 방법으로 생각해야한다.
         
        isNew() 기본 로직은 아래와 같다.
        - 식별자가 객체이면 null 일 경우 true
        - 식별자가 primitive type 이면 0 일 경우 true
         

        데이터 업데이트는 영속상태의 엔티티에 대해서 변경감지를 이용

         
        이유는 merge() 를 사용하면 비/준영속 상태의 엔티티에 대해서 merge() 를 호출하면
        비/준영속 엔티티의 값으로 모두 교체된 새로운 영속 엔티티가 반환되고..
        이는 commit 시에 변경감지가 동작하여 최악의 경우 모두 null 로 업데이트 되는 상황이
        생길 수 있기 때문이다.
         
        그럼 merge() 는 언제 사용하는 것인가..
        단순히 비/준영속 상태의 엔티티를 영속상태의 엔티티로 변경할 때 사용하는 것이다. (매우 특수한 상황)
        (주의, 데이터 변경 없어야함)
         
        참고>
        JPA 의 변경감지 기본 전략은 "모든" 필드를 업데이트 하는 것이다.
        (수정된 데이터만 동적으로 업데이트 하려면 Hibernate DynamicUpdate 전략 이용)
        -> 보통 컬럼이 30개 이상 되면 DynamicUpdate 방식이 빠르다.
        (그러나, 30개 이상이면 책임이 적절히 분리 안되었을 가능성이 높다.)
         

        반응형

        'Spring > DB, Cache 연동' 카테고리의 다른 글

        JPA 변경 감지와 플러시  (0) 2023.06.15
        JPA Entity Default Constructor  (1) 2023.06.07
        Spring Cache Annotation  (0) 2023.06.04
        Spring Data Redis  (0) 2023.06.03
        Spring 의 DB 연동 기술 히스토리 요약  (0) 2023.03.10
        다음글
        다음 글이 없습니다.
        이전글
        이전 글이 없습니다.
        댓글
      조회된 결과가 없습니다.
      스킨 업데이트 안내
      현재 이용하고 계신 스킨의 버전보다 더 높은 최신 버전이 감지 되었습니다. 최신버전 스킨 파일을 다운로드 받을 수 있는 페이지로 이동하시겠습니까?
      ("아니오" 를 선택할 시 30일 동안 최신 버전이 감지되어도 모달 창이 표시되지 않습니다.)
      목차
      표시할 목차가 없습니다.
        • 안녕하세요
        • 감사해요
        • 잘있어요

        티스토리툴바