이번 시간에는 JPA EntityGraph에 대해 간단히 알아보고자 합니다.
JPA 2.0까지는 엔터티 연결을 로드하기 위해 일반적으로 FetchType을 사용했습니다. LAZY 및 FetchType Lazy 또는 EAGER를 통해서 JPA 제공자에게 관련 연관을 추가로 로딩합니다.
그러나 FetchType은 정적이며 런타임에 이 두 전략 사이를 전환할 수 없습니다.
JPA 엔터티 그래프의 주요 목표는 엔터티의 관련 연결 및 기본 필드를 로드할 때 런타임 성능을 개선하는 것입니다.
간단히 말해서 JPA는 하나의 선택 쿼리에서 모든 그래프를 로드한 다음 더 많은 SELECT 쿼리와의 연결 가져오기를 방지합니다. 이것은 응용 프로그램 성능을 향상시키기 위한 좋은 접근 방식입니다.
EntityGraph를 코드로 예를 들어서 개념을 잡아보실께요 (실제 동작 코드는 아니고 개념을 설명하기 위한 코드입니다.)
예) 스토리를 쓸 수 있는 작성자를 각각 엔티티로 만들고 1:N연관관계를 맺었습니다.()
// Writer.kt (Entity)
@Entity
class Writer(
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
val id: Long,
val name: String,
@OneToMany(fetch = FetchType.LAZY)
@JoinColumn(name = "writer_id")
var storyList:MutableList<Story>
)
// Story.kt (Entity)
@Entity
class Story(
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
val id: Long,
val title: String,
val content: String
)
@Repository
interface WriterRepository : JpaRepository<Writer, Long> {
override fun findById(id: Long): Optional<Writer>
@EntityGraph(attributePaths = ["story"])
override fun findByIdWithStory(id: Long): Optional<Writer>
}
Story 엔티티의 FetchType이 Lazy로 되어 있기때문에 Writer엔티티에서 story객체를 사용하려고 할때 story객체수 만큼 Select쿼리가 나갑니다.
반면 findByIdWithStory같은 경우는 @EntityGraph 애노테이션이 걸려 있어서 Join 쿼리 한번만 나가게 됩니다.
findById 쿼리
select writer from writer where writer_id = ?
@EntityGraph 적용된 findByIdWithStory 쿼리
select * from writer left outer join story where writer_id=?
- EntityGraphType
- FETCH불러오게 합니다.
- 지정한 연관관계 엔티티는 Eager로딩으로 불러오고, 그외 연관관계 엔티티들은 자동적으로 LAZY 로딩으로
- LOAD해당 연관관계 어노테이션에서 가지고 있는 FetchType Default 값으로 설정해서 불러옵니다.
- 지정한 연관관계 엔티티는 Eager로딩을 통해 불러오며, 그외의 엔티티 데이터들은 직접 선언한 FetchType이나
정리
오늘은 EntityGraph에 대해 간단히 알아보았습니다. 개념을 잘 파악하시어 프로젝트에 적절하게 사용하시길 바랍니다.
'IT > JPA' 카테고리의 다른 글
JPA의 낙관적 락과 비관적 락을 통해 엔티티에 대한 동시성 제어에 대해 알아보자 (0) | 2023.04.16 |
---|---|
JPA EntityManager 라이프사이클에 대해 알아보자 (1) | 2023.04.14 |
JPA 상속 전략에 대해 알아보자 (0) | 2023.04.06 |
JPA Entity Manager를 알아보자 (0) | 2023.04.05 |
JPA 영속성 컨텍스트를 알아보자 (0) | 2023.04.04 |