지연 로딩과 즉시 로딩
즉시 로딩
엔티티를 조회할 때, 연관된 엔티티도 같이 조회 → 가능하면 조인 쿼리를 사용해서 쿼리한번만 사용
em.find(Member.class, “member1”)
호출시, 회원 엔티티와 연관된 팀 엔티티도 함께 호출됨- 설정 방법 :
@ManyToOne(fetch = FetchType.EAGER)
지연 로딩
연관된 엔티티를 실제 사용할 때 조회 → 프록시 객체 사용
member.getTeam().getName()
처럼 조회한 팀 엔티티를 실제 사용하는 시점에 SQL이 호출되어 팀 엔티티를 조회- 설정 방법 :
@ManyToOne(fetch = FetchType.LAZY)
지연로딩을 이용한 프록시 조회
지연 로딩 설정
@Entity
public class Member
@Id
@GeneratedValue
private Long id;
@Column(name = "USERNAME")
private String name;
@ManyToOne(fetch = FetchType.LAZY) //**
@JoinColumn(name = "TEAM_ID")
private Team team;
..
}
지연로딩 실행
Member member = em.find(Member.class, "member1");
Team team = member.getTeam(); // 프록시 객체 탐색
team.getName(); //팀 객체 실제 사용 -> DB 조회시점
즉시 로딩을 이용한 함께 조회
즉시 로딩 설정
@Entity
public class Member
@Id
@GeneratedValue
private Long id;
@Column(name = "USERNAME")
private String name;
@ManyToOne(fetch = FetchType.EAGER) //**
@JoinColumn(name = "TEAM_ID")
private Team team;
..
}
즉시 로딩 실행
Member member = em.find(Member.class, "member1"); //DB조회 시점
Team team = memeber.getTeam();
실무에서 즉시로딩을 사용하지 않는 이유
- 즉시 로딩을 적용하면 예상하지 못한 SQL이 발생
ex) 만약 엔티티에서 즉시로딩으로 설정 되어있을 경우,em.createQuery(”select m from Member m”, Member.class).getResultList();
로 조회하면, createQuery안의 select 문 + team과 조인된 select 문 2개의 SQL이 실행되어 버린다. - 즉시 로딩은 JPQL에서 N+1 문제를 일으킨다
@ManyToOne
,@OneToOne
은 기본이 즉시 로딩 → LAZY로 설정 할것!
정리
- 모든 연관관계에 지연 로딩을 사용해라
- 실무에서 즉시 로딩을 사용하지 말것!
- JPQL fetch 조인이나, 엔티티 그래프 기능을 사용할것
- 즉시 로딩은 예약하지 못하는 쿼리가 나간다.
참고
해당 글은 김영한님의 자바 ORM 표준 JPA 프로그래밍을 공부하며 작성한 글입니다.
https://www.inflearn.com/course/ORM-JPA-Basic/dashboard
반응형