Post

[JPA] 즉시(Eager)로딩 지연(Lazy)로딩

즉시로딩 지연로딩

지연로딩


  • fetch 옵션을 Lazy했을 때 가져온 객체는 프록시 객체로 가져와서 실제로 사용할 때(+컨텍스트 관리도 받을때) 초기화 되어서 실제 entity와 연결된다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
@ManyToOne(fetch = FetchType.LAZY)//Lazy로 하면 Team은 프록시 객체로 준다.
@JoinColumn(insertable = false, updatable = false, name = "TEAM_ID") //읽기 전용 필드 옵션
private Team team;

Member member = new Member();
member.setUsername("John");

Team team = new Team();
team.setName("teamA");

em.persist(member);

team.getMembers().add(member);

em.persist(team);

em.flush();
em.clear();

Member findMember = em.find(Member.class, member.getId());

System.out.println("m= "+findMember.getTeam().getClass());

---

m= class hellojpa.Team$HibernateProxy$Flm1Zq0H
  • 따라서 자주 같이 사용하면 fetch 옵션을 eager로 줘서 즉시로딩으로 같이 쓸 수 있다.

즉시로딩


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(insertable = false, updatable = false, name = "TEAM_ID") //읽기 전용 필드 옵션
private Team team;

Member member = new Member();
member.setUsername("John");

Team team = new Team();
team.setName("teamA");

em.persist(member);

team.getMembers().add(member);

em.persist(team);

em.flush();
em.clear();

Member findMember = em.find(Member.class, member.getId());

System.out.println("m= "+findMember.getTeam().getClass());

---

m = class hellojpa.Team

프록시와 즉시로딩 주의


  • 실무에선 가급적 지연로딩만 사용!
  • 즉시 로딩은 SQL문제가 발생할 수 있기 때문.
  • 즉시 로딩은 JPQL에서 N+1문제를 일으킬 수 있기 때문.(조인문으로 가져온 것들에서 관련된 객체들 전부 가져오기 때문이다.)
  • @ManyToOne, @OneToOne할 때는 디폴트가 즉시로딩이기 때문에 지연로딩으로 아예 해버려야 한다.

지연 로딩 활용


  • Member와 Team은 자주 함께 사용 → 즉시 로딩
  • Member와 Order는 가끔 사용 → 지연 로딩
  • Order와 Product는 자주 함께 사용 → 즉시 로딩
  • JPQL fetch 조인을 사용해서 즉시 로딩을 사용해라(기본으로 다 Lazy로 하고)
This post is licensed under CC BY 4.0 by the author.

Comments powered by Disqus.