JPA

JPA 즉시 로딩과 지연 로딩

으엉어엉 2024. 8. 25. 17:30
728x90

 

 

Member Class

@ManyToOne(fetch = FetchType.LAZY)//member은 many , team은 one
@JoinColumn(name="TEAM_ID") //외래키랑 맵핑
private Team team;

 

JpaMain Class

 

Team team1 = new Team();
team1.setName("teamA");
em.persist(team1);

Member member1 = new Member();
member1.setUsername("MemberA");
member1.setTeam(team1);
em.persist(member1);

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

Member m1 = em.find(Member.class, member1.getId());
System.out.println("m1 = " + m1.getTeam().getClass());

 

 

멤버랑 팀이랑 자주 사용한다면??? 

 

프록시와 즉시로딩 주의

• 가급적 지연 로딩만 사용(특히 실무에서)

아래는 문제들이 생기는 것들

 

• 즉시 로딩을 적용하면 예상하지 못한 SQL이 발생

-> 예제가 많아질수록 성능이 떨어진다. Join이 개수만큼 늘어나기 때문이다.

 

• 즉시 로딩은 JPQL에서 N+1 문제를 일으킨다.

-> 

List <Member> result = em.createQuery("select m from Member m", Member.class).getResultList();

 

현재 멤버와 팀이 2개이므로 2개가 select 된다. 

Member갯수만큼 

@ManyToOne(fetch = FetchType.EAGER)

와 계속 왔다갔다 한다.  처음 쿼리 1개 + N개 이므로 N+1이게 된다. 

Lazy로 하면 Team의 쿼리가 나오지 않는다.

지연로딩으로 다 한 다음에 

  1. Fatch Join ( 동적으로 원하는 애들을 선택할 수 있는 것)을 사용한다.

• @ManyToOne, @OneToOne은 기본이 즉시 로딩 -> LAZY로 설정 

• @OneToMany, @ManyToMany는 기본이 지연(LAZY) 로딩

 

 

 

지연 로딩의 활용

• Member와 Team은 자주 함께 사용 -> 즉시 로딩

• Member와 Order는 가끔 사용 -> 지연 로딩

• Order와 Product는 자주 함께 사용 -> 즉시 로딩

 

하지만 실무에서는 다 지연로딩을 사용하는 것을 권장한다.

 

 

 

 

 

JPQL fetch 조인이나, 엔티티 그래프 기능을 사용한다.

 

다 좋지만 지연로딩 꼭 사용하자.

728x90

'JPA' 카테고리의 다른 글

JPA 고아객체  (0) 2024.08.25
JPA 영속성 전이 CASCADE  (0) 2024.08.25
JPA Proxy  (0) 2024.08.25
JPA 상속관계 맵핑  (0) 2024.08.22
JPA 연관관계 매핑  (0) 2024.08.22