8장. 프록시 - 지연로딩
- 📚 Spring/Spring JPA
- 2023. 8. 30. 07:57
| ⚡ 지연로딩
- 실무에서 모든 연관관계는 지연로딩을 사용해라.
- 실무에서 즉시 로딩을 사용하지 마라.
- JPQL fetch 조인이나, 엔티티 그래프 기능을 사용해라
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public abstract class Item {
@Id @GeneratedValue
private Long id;
private String name;
private int price;
}
@Entity
public class Member extends BaseEntity {
@Id
@GeneratedValue
@Column(name = "MEMBER_ID")
private Long id;
@Column(name = "USERNAME")
private String username;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "TEAM_ID")
private Team team;
}
public class JpaMain {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
try {
Team team = new Team();
team.setName("teamA");
em.persist(team);
Member member = new Member();
member.setUsername("kuser");
member.setTeam(team);
em.persist(member);
em.flush();
em.clear();
Member m = em.find(Member.class, member.getId());
// 해당 시점에는 프록시 객체이다.
System.out.println("m = " + m.getTeam().getClass());
//m = class hellojpa.Team$HibernateProxy$bqLHLVBG
System.out.println("=-=============");
// 사용하는 시점에 DB에서 조회한한다.
System.out.println(m.getTeam().getName());
tx.commit();
} catch (Exception e) {
tx.rollback();
} finally {
em.close();
}
emf.close();
}
}
지연로딩은 처음 MEMBER를 조회할 때 TEAM은 프록시 객체이며, 실제 TEAM객체를 불러올 때 DB에서 조회한다.
| ⚡ 즉시로딩 (EAGER)
- 조회하는 시점에 조인하여 같이 조회한다.
- MEMBER를 조회할 때 TEAM도 같이 조인하여 조회한다.
- 실무에서는 즉시로딩을 쓰면 안된다.
- 즉시로딩을 적용하면 예상하지 못한 SQL이 발생한다.
- 즉시로딩은 JPQL에서 N+1 문제를 일으킨다.
- @ManyToOne, @OneToOne은 기본이 즉시로딩 -> LAZY로 설정
- @OneToMany, @ManyToNamy는 기본이 지연 로딩이다.
@Entity
public class Member extends BaseEntity {
@Id
@GeneratedValue
@Column(name = "MEMBER_ID")
private Long id;
@Column(name = "USERNAME")
private String username;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "TEAM_ID")
private Team team;
}
결과
select
member0_.MEMBER_ID as MEMBER_I1_2_0_,
member0_.createdBy as createdB2_2_0_,
member0_.createdDate as createdD3_2_0_,
member0_.lastModifiedBy as lastModi4_2_0_,
member0_.lastModifiedDate as lastModi5_2_0_,
member0_.TEAM_ID as TEAM_ID7_2_0_,
member0_.USERNAME as USERNAME6_2_0_,
team1_.TEAM_ID as TEAM_ID1_3_1_,
team1_.createdBy as createdB2_3_1_,
team1_.createdDate as createdD3_3_1_,
team1_.lastModifiedBy as lastModi4_3_1_,
team1_.lastModifiedDate as lastModi5_3_1_,
team1_.name as name6_3_1_
from
Member member0_
left outer join
Team team1_
on member0_.TEAM_ID=team1_.TEAM_ID
where
member0_.MEMBER_ID=?
'📚 Spring > Spring JPA' 카테고리의 다른 글
8장. 프록시 (0) | 2023.08.28 |
---|---|
다대일 단반향 - 다대일 양방향 (0) | 2023.08.27 |
[Spring JPA #7] 7장. 고급매핑 (0) | 2023.08.26 |
[정리] 준영속 (0) | 2022.03.17 |
[정리] 플러시 (flush()) (0) | 2022.03.16 |