본문 바로가기

Framework/JPA

[JPA] Proxy 객체 / 지연 로딩(LAZY), 즉시 로딩(EAGER)

반응형

Proxy 객체

 - 실제 객체를 상속받아 만들어지는 객체

 - 실제 객체를 참조(Target)를 보관

 - Proxy 객체 메서드 호출 시 실제 객체의 메서드 호출

 - 실제 사용시 초기화 (DB 조회)

Member refMember = em.getReference(Member.class, 1L); // Proxy 객체 불러옴
refMember.getName(); // 초기화

 -> em.find는 실제 객체를 불러옴 em.getReference() != em.find()

지연 로딩 (LAZY)

 - 조회 시 실제 객체가 아닌 Proxy 객체를 가져옴

 - 실제 사용하는 시점에서 초기화 (DB 조회)

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "TEAM_ID")
private Team team;
Member member = em.find(Member.class, 1L);
member.getTeam(); // Proxy 객체
member.getTeam().getName(); // 초기화

 

즉시 로딩 (EAGER)

 - 조회 시 실제 객체를 조회해옴

 - 가능하면 조인해서 한번에 DB 조회 -> 조인이 불가능할 경우 쿼리가 한번 더 나감

@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "TEAM_ID")
private Team team;
Member member = em.find(Member.class, 1L);
member.getTeam(); // 실제 객체

 

 즉시 로딩 (EAGER) 주의점

  - N+1 문제를 발생

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

       SQL) SELECT * FROM member m; -> 1번 수행

       SQL) SELECT * FROM team t; -> N번 수행

 

  - 가급적 지연 로딩(LAZY)을 사용

  - 필요 시 Fetch Join이나 엔티티 그래프 사용

  Fetch Join ex)

List<Member> members = em.createQuery("select m from Member m join fetch m.team", Member.class)
        .getResultList();

  - @ManyToOne, @OneToOne 의 기본 설정은 즉시 로딩 (EAGER) 이므로 지연 로딩 (LAZY)로 바꿔주는게 좋음

반응형

'Framework > JPA' 카테고리의 다른 글

[JPA] 기본 키 자동 생성 - @Id, @GenarateValue 전략  (0) 2022.04.06