[5] 스프링 데이터 JPA (5) - 쿼리 메소드 기능 3 (벌크성 수정 쿼리-@Modifying, @EntityGraph)

김정욱·2021년 4월 14일
3
post-thumbnail

목차

  • 벌크성 수정 쿼리
  • @EntityGraph
  • JPA Hint & Lock

벌크성 수정 쿼리

[ 개념 & 설명 ]

  • 특정 하나가 아닌 다수의 데이터수정하는 쿼리를 말한다
  • JPA에서는 데이터 수정'변경감지'를 통해 값을 수정한다
  • 변경 데이터가 많을 때 굳이 하나씩 '변경감지'를 일으켜서 하면 비효율적이다
  • 순수 JPA를 사용하며 em.createQuery(...).executeUpdate()사용해서 벌크성 수정 쿼리를 사용한다
  • 스프링 데이터 JPA에서는 이러한 벌크성 수정 쿼리편리하게 사용하기 위한 방법을 제공한다

[ 순수 JPA와 사용 비교 ]

(순수 JPA)

  • update 쿼리를 작성 후에 반드시 executeUpdate()를 통해 실행
    -->반영된 레코드의 수반환

(스프링 데이터 JPA)

  • JpaRepository를 상속받는 인터페이스@Query를 통해 JPQL작성한 것
  • @Modifying을 사용해서 조회를 위한 getResultList()getSingleResult()가 아닌
    exeCuteUpdate()실행되도록 지정!
  • 반드시 벌크성 수정 쿼리에는 @Modifying이 있어야 한다
    • 없으면 ? --> QueryExecutionRequestException 오류 발생

[ @Modifying 사용시 주의할 점 ]

  • 벌크성 수정 / 삭제 쿼리영속성 컨텍스트거치지 않고 수행된다
    --> 기존에 영속성 컨텍스트에 남아있는 데이터불일치발생시킬 수 있다
  • 벌크성 수정 / 삭제 쿼리를 한 후에는 반드시 영속성 컨텍스트초기화 시켜야 한다
    (혹은 영속성 컨텍스트엔티티가 관리되기 전에 수행해도 괜찮다)
  • 순수 JPA Repository라면 em.flush() / em.clear()를 해야하지만 스프링 데이터 JPA는 이러한 기능을 옵션으로 제공
    --> @Modifying(clearAutomatically = true)

@EntityGraph

[ 개념 & 설명 ]

  • JPA를 사용하면서 Entity 연관관계LAZY fetch때문에 N+1문제가 자주 발생한다
  • N+1문제fetch join을 통해서 관련 엔티티를 한번에 조회해서 문제를 해결한다
  • @EntityGraph스프링 데이터 JPA에서 JPQL없이 fetch join을 수행하게 도와주는 어노테이션이다
  • 기본적으로 LEFT OUTER JOIN이 수행
    (fetch join을 하면 연관 테이블을 묶어주기도 하지만, select 절에 모든 컬럼을 추가하기도 함)

[ 순수 JPA와 사용 비교 ]

(순수 JPA)

  • @EntityGraph는 기본적으로 left join으로 동작해서 맞췄다
  • 연관 엔티티들이 많아지면 JPQL 쿼리가 상당히 길어지고 오타가 날 수도 있다

(@EntityGraph)

  • 3가지 방법 모두 @EntityGraph를 사용해 내부적으로 fetch join수행하는 코드
  • 어떤 메소드를 쓰냐에 따라도 다르며(기존정의 / 쿼리메소드) / 스타일에 따라서도 다를 수 있다
  • 3가지 방법
    • @EntityGraph + @Query
      : 기본 틀이되는 코드를 @Query로 작성하고 내부적으로 fetch join실행하게 설정
    • @EntityGraph + @Override
      : findAll()처럼 쿼리메소드가 아닌 기존에 정의된 메서드사용할 때에는 반드시 @Override 해야함
    • @EntityGraph + 쿼리메소드
      : 쿼리메소드사용하며 내부적으로 fetch join이 수행되도록 설정

[ 추가 : @NamedEntityGraph ]

  • 실무에서 잘 사용되는 방법은 X / 표준이니까 알아두자
  • NamedQuery처럼 Entity에 연관된 객체를 attributeNodes로 등록하고 필요시 @EntityGraph사용
  • 굳이 Entity 내부에 지정해야 하기 때문에 실무에서 잘 쓰이지는 X
  • 사용
    • Member Entity@NamedEntityGraph로 지정
    • 인터페이스 repository에 가져와서 쿼리 생성

[ 정리 ]

  • 권장
    • @Query를 사용해서 JPQL로 직접 fetch join을 사용하는 방법
    • @EntityGraph를 통해 간단한 fetch join 사용하는 방법

JPA Hint & Lock

[ JPA Hint ]

  • 일반적인 조회객체 상태의 정보를 유지하기 위한 다양한 과정수행된다
    --> 변경감지를 위한 스냅샷 저장 등등
  • 오로지 조회가 목적인 경우 이러한 과정은 불필요하며 이런 부분을 최적화 하는 것이 JPA Hint
  • 실제 성능 이슈느껴질 때 최적화 하면 된다
    --> 굳이 조회목적인 부분모두 처리해줄 필요는 X (생각보다 최적화 효과미비할 확률이 큼)
  • 사용
  • 추가 (Page 사용시 추가쿼리에도 적용하는 방법)

[ JPA Lock ]

  • JPA가 제공하는 Lock어노테이션으로 사용하는 것
  • 트랜잭션간에 발생하는 Lock과 관련된 내용
  • 개념적으로 깊은 내용이라 추가적으로 공부가 필요
profile
Developer & PhotoGrapher

0개의 댓글