네로개발일기

개발자 네로의 개발 일기, 자바를 좋아합니다 !

반응형

EntityGraph란,

- 엔티티들은 서로 연관되어 있는 관계가 보통이며 이 관계는 그래프로 표현이 가능하다. EntityGraph는 JPA가 어떤 엔티티를 불러올 때 이 엔티티와 관계된 엔티티를 불러올 것인지에 대한 정보를 제공한다.

 

// getter/setter ...
@Entity
@Table(name = "user")
public class User {

    // other properties
    
    @ToString.Exclude
    @OneToMany(fetch = FetchType.LAZY)
    @JoinColumn(name = "user_id")
    private List<Address> addresses = new ArrayList<>();
}
@Repository
public interface UserRepository extends JpaRepository<User, Long> {

    Optional<User> findById(Long userId);
    
    @EntityGraph(attributePaths = {"addresses"}, type = EntityGraph.EntityGraphType.LOAD)
    Optional<User> findWithAddressesById(Long userId);
}

addresses 가 LAZY이기 때문에 findById로 패치한 User 엔티티에서 addresses에 접근하면 그 때 달려있는 addresses 개수 만큰 select 쿼리를 날린다. 하지만 findWithAddressesById는 @EntityGraph 어노테이션으로 addresses도 함께 패치해오도록 해두었기 때문에 1번의 fetch join 쿼리만 실행된다.

 

/*
 * findById 쿼리
 */
select
    user0_.id as id1_10_0_,
    user0_.username as username2_10_0_
from
    user user0_
where
    user0_.id=?

/*
 * @EntityGraph 달린 findWithAddressesById 쿼리
 */
select
    user0_.id as id1_10_0_,
    addresses1_.id as id1_5_1_,
    user0_.username as username2_10_0_,
    addresses1_.street as street2_5_1_,
    addresses1_.user_id as user_id3_5_0__,
    addresses1_.id as id1_5_0__
from
    user user0_
left outer join
    address addresses1_
        on user0_.id=addresses1_.user_id
where
    user0_.id=?

fetch type을 바꿀 필요도 없고, Querydsl이나 JPQL 같은 쿼리를 별도로 만들지 않아도 되기 때문에 편하다.

 

@EntityGraph의 type은 EntityGraph.EntityGraphType.FETCH 와 EntityGraph.EntityGraphType.LOAD 두가지가 있다.

- FETCH: entity graph에 명시한 attribute는 EAGER로 패치하고, 나머지 attribute는 LAZY로 패치

- LOAD: entity graph에 명시한 attribute는 EAGER로 패치하고, 나머지 attribute는 entity에 명시한 fetch type이나 디폴트 FetchType으로 패치 ( @OneToMany는 LAZY, @ManyToOne은 EAGER 등이 디폴트이다. )

728x90
반응형
blog image

Written by ner.o

개발자 네로의 개발 일기, 자바를 좋아합니다 !