kok202
@EntityGraph : FetchType.EAGER 일 경우 Select 쿼리 줄이기

2019. 6. 15. 03:19[정리] 기능별 개념 정리/JPA

예시

@Data
@Entity("member")
public class MemberEntity{
	@Id
	@GeneratedValue
	private long id;

	private String name;
    
	@OneToOne
	@JoinColumn("country_id")
	private CountryEntity country;
}
@Data
@Entity("country")
public class CountryEntity{
	@Id
	@GeneratedValue
	private long id;

	private String name;
}
public interface MemberRepository extends JpaRepository<MemberEntity, Long> {
	List<MemberEntity> findByName(String name);
}

 

MemberEntity memberEntity = memberRepository.findByName("kok202").get();

맵핑 정보가 @ManyToOne, @OneToOne 일 경우 기본 Fetch 전략이 EAGER 이다.

EAGER 를 해오는 방식을 두가지로 생각해볼 수 있다.

방법 1. 조인을 해서 데이터를 한번에 가져온다.

방법 2. Fetch eager 인 데이터들을 대상으로 select 쿼리를 한번 더 날려서 가져온다.

 

JPA는 이전에는 방법 1을 이용하여 fetch eager 를 구현하였으나 방법 2로 변경되었다.

그래서 위 예시의 findByCountry 쿼리는 총 두개의 쿼리가 발생시킨다.

1. select * from member where member.name = 'kok202'

2. select * from country where country.id = ?

 

select 쿼리에 join 을 시켜서 데이터를 가져오게함으로서 select 쿼리의 발생을 줄이고 싶다면 @EntityGraph 를 사용할 수 있다.

public interface MemberRepository extends JpaRepository<MemberEntity, Long> {
	@EntityGraph(attributePaths = "country")
	List<MemberEntity> findByName(String name);
}

country 를 fetch eager 해올 때는 조인을 통해 가져온다.

위의 결과는 하나의 쿼리만 발생시킨다.

select * from member inner join country on country.id = member.country_id where member.name = 'kok202' 

 

 

 

 

 

번외 EntityGraphType (기본값 : EntityGraphType.FETCH)

@EntityGraph(attributePaths = "country", type = EntityGraphType.FETCH)
@EntityGraph(attributePaths = "country", type = EntityGraphType.LOAD)

EntityGraphType.FETCH : attributePaths 정의한 멤버변수만 EAGER 로 불러오고 나머지는 LAZY 로 불러온다. 즉 멤버변수의 FetchType이 뭐였는지 신경쓰지 않는다. FetchType.EAGER 인 멤버변수가 있었어도 EntityGraph 의 attributePaths 에 정의되어있지 않다면 Lazy 로 불러오게 된다.

 

EntityGraphType.LOAD : attributePaths 정의한 멤버변수는 EAGER 로 불러오고 나머지 멤버변수는 각자의 FetchType을 존중해서 불러온다.

 

출처 : https://www.youtube.com/watch?v=Ec17RS8R7zc

 

 

 

 

 

'[정리] 기능별 개념 정리 > JPA' 카테고리의 다른 글

JPA : Query 발생 시점  (0) 2019.06.17
JPA : Embeddable  (0) 2019.06.17
JPA fetch 맵핑별 기본값  (0) 2019.06.14
JPA delete  (0) 2019.06.12
Differences between @Entity(name) and @Table(name)  (0) 2019.05.20