[JPA & Hibernate] Eager Fetch vs Lazy Fetch

원알렉스·2020년 8월 11일
0

JPA

목록 보기
6/16
post-thumbnail
post-custom-banner

깃허브 소스코드
Udemy 강의영상

🚀 Fetch Type이란

     Fetch Type은 JPA가 하나의 엔티티를 조회할 때, 연관 관계에 있는 객체들을 어떻게 가져올 것이냐를 나타내는 설정값입니다.

Fetch Type은 크게 EagerLazy 두 가지의 전략이 있습니다. Eager 전략은 엔티티를 조회할 때, 연관 관계에 있는 엔티티도 함께 가져오고, 반대로 Lazy 전략은 연관 관계 엔티티를 참조할 때 그때서야 가져오게 됩니다.

✔ 실행되는 쿼리문 비교

     일대일 연관관계를 가지는 학생(Student) 엔티티와 여권(Passport) 엔티티를 가지고 실행되는 쿼리문을 비교해 보겠습니다.

@Entity
@Table(name = "students")
@Getter
@Builder
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Student {

    @Id
    @GeneratedValue
    private Long id;

    @Setter
    @Column(name = "name", nullable = false, length = 100)
    private String name;

    @OneToOne(fetch = FetchType.LAZY)
    //@OneToOne(fetch = FetchType.EAGER)
    private Passport passport;

    @UpdateTimestamp
    @Column(name = "updated_date")
    private LocalDateTime updatedDate;

    @CreationTimestamp
    @Column(name = "created_date")
    private LocalDateTime createdDate;

    @Override
    public String toString() {
        return String.format("Student[%s]", this.name);
    }
}
@Entity
@Table(name = "passports")
@Getter
@Builder
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Passport {

    @Id
    @GeneratedValue
    private Long id;

    @Setter
    @Column(name = "number", nullable = false, length = 100)
    private String number;
    
    @OneToOne(mappedBy = "passport")
    private Student student;

    @UpdateTimestamp
    @Column(name = "updated_date")
    private LocalDateTime updatedDate;

    @CreationTimestamp
    @Column(name = "created_date")
    private LocalDateTime createdDate;

    @Override
    public String toString() {
        return String.format("Passport[%s]", this.number);
    }
}

아래의 테스트 코드를 실행해 보면 결과는 다음과 같습니다.

@Test
@Transactional
public void retrieveStudentAndPassportDetails() {
    Student student = entityManager.find(Student.class, 20001L);
    logger.info(String.format("Student[%s]", student.getName()));
    logger.info(String.format("Passport[%s]", student.getPassport().getNumber()));
}

⬇ Lazy Fetch 쿼리 결과 ⬇

Student 엔티티를 조회할 때, Student 정보만 조회를 하고 getter로 연관 관계 엔티티인 Passport를 참조할 때 그때서야 Passport 정보를 조회합니다.

⬇ Eager Fetch 쿼리 결과 ⬇

Student 엔티티를 조회할 때, left outer join으로 Passport 정보도 함께 조회합니다.

profile
Alex's Develog 🤔
post-custom-banner

0개의 댓글