[Spring JPA] 즉시로딩과 지연로딩
2021. 6. 28. 18:51ㆍSpring/JPA
즉시로딩과 지연로딩
Member를 조회할 때 Team도 함께 조회해야 할까?
- 단순히 member 정보만 사용하는 비즈니스 로직
Println(member.getName());
지연로딩 LAZY을 사용해서 프록시로 조회
@Entity
public class Member {
@Id
@GeneratedValue
@Column(name = "MEMBER_ID")
private Long id;
@ManyToOne(fetch = FetchType.LAZY)//이 부분이 LAZY
@JoinColumn(name = "TEAM_ID")
private Team team;
지연로딩
지연 로딩 LAZY을 사용해서 프록시로 조회
Member member = em.find(Member.class, 1L);
Team team = member.getTeam();
Team.getName(); // 실제 team을 사용하는 시점에 초기화(DB 조회)
실제 코드
Team team = new Team();
team.setName("teamA");
em.persist(team);
Member member1 = new Member();
member1.setUsername("hello");
member1.setTeam(team);
em.persist(member1);
em.flush();
em.clear();
Member m = em.find(Member.class, member1.getId());
System.out.println("m.getTeam().getClass() = " + m.getTeam().getClass()); // 프록시로 가져온다.
System.out.println("==============");
m.getTeam().getName(); // 실제 team을 사용하는 시점에 프록시를 초기화하고 실제 값을 가져온 다.
System.out.println("==============");
즉시 로딩 EAGER를 사용해서 함께 조회
@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; ..
}
즉시로딩
- 즉시로딩(EAGER)는 Member 조회시 항상 Team도 조회
- JPA 구현체는 가능하면 조인을 사용해서 SQL 한번에 함께 조회
프록시와 즉시로딩 주의!!!
- 가급적 지연 로딩만 사용(특히 실무에서)
- 즉시 로딩을 적용하면 예상하지 못한 SQL이 발생
- 즉시 로딩은 JPQL에서 N + 1 문제를 일으킨다.
- @ManyToOne, @OneToOne은 기본이 즉시 로딩 ➔ LAZY로 설정
- @OneToMany, @ManyToMany는 기본이 지연 로딩
지연 로딩 활용 - 실무
- 모든 연관관계에 지연 로딩을 사용해라!
- 실무에서 즉시 로딩을 사용하지 마라!
- JPQL fetch 조인이나, 엔티티 그래프 기능을 사용해라!
- 즉시 로딩은 상상하지 못한 쿼리가 나간다.
참고자료
'Spring > JPA' 카테고리의 다른 글
Java8 Stream 특정 Key 중복제거 (0) | 2022.05.30 |
---|---|
JPQL은 만능이 아니다! (0) | 2021.12.23 |
Spring JPA [상속관계 맵핑] (0) | 2021.06.17 |
[Spring JPA] 다양한 연관관계 매핑 (0) | 2021.04.19 |
Spring JPA 영속성 컨텍스트 (0) | 2021.02.28 |