즉시로딩, 지연로딩

Mina Park·2022년 9월 11일
0

1) 즉시로딩

  • FetchType.EAGER
  • JPA 구현체는 가능하면 조인을 사용해서 SQL 한번에 함께 조회

2) 지연로딩

  • FetchType.LAZY
 @ManyToOne 디폴트값은 FetchType.EAGER(한꺼번에 쿼리)
    @ManyToOne(fetch = FetchType.LAZY) //지연로딩 사용해서 프록시로 조회
    @JoinColumn(name = "TEAM_ID")
    private TeamMapping team;
 			TeamMapping team = new TeamMapping();
            team.setName("teamA");
            em.persist(team);

            MemberMapping member1 = new MemberMapping();
            member1.setUsername("hello");
            member1.setTeam(team);
            em.persist(member1);

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

            MemberMapping m = em.find(MemberMapping.class, member1.getId()); //영속성 컨텍스트에 올라감
            System.out.println("m = " + m.getTeam().getClass()); //proxy
            System.out.println("==============");
            m.getTeam().getName(); //프록시 초기화(이 시점에 team 조회 쿼리)
            System.out.println("==============");

            tx.commit();
m = class hellojpa.mapping.TeamMapping$HibernateProxy$Js9npXxJ
==============
Hibernate: 
    select
        teammappin0_.TEAM_ID as team_id1_12_0_,
        teammappin0_.createdAt as createda2_12_0_,
        teammappin0_.createdBy as createdb3_12_0_,
        teammappin0_.updatedAt as updateda4_12_0_,
        teammappin0_.updatedBy as updatedb5_12_0_,
        teammappin0_.name as name6_12_0_ 
    from
        TeamMapping teammappin0_ 
    where
        teammappin0_.TEAM_ID=?
==============
m again = class hellojpa.mapping.TeamMapping$HibernateProxy$Js9npXxJ
9월 11, 2022 9:54:25 오후 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl$PoolState stop
INFO: HHH10001008: Cleaning up connection pool [jdbc:h2:tcp://localhost/~/test]

Process finished with exit code 0

📌실무에서 주의할 점

  • 가급적 지연로딩만 사용!!!
  • (1) 즉시로딩 적용시 문제점?
    • 예상치 못한 SQL 발생
    • 실무에서는 많은 테이블을 한꺼번에 조인해오면서 성능이슈 발생
    • JPQL에서 N+1 문제를 일으킴(1번의 쿼리를 날리고, 이후 조회된 데이터 N개만큼 추가 쿼리)
   List <Member> members = em.createQuery("select m from Member m", Member.class).getResultList();
  • em.find()의 경우 PK를 딱 찍어서 가져오기 때문에 즉시로딩 옵션이 있으면 조인으로 쿼리 한 방에 가져옴
  • JPQL의 경우 SQL로 그대로 번역하기 때문에 당연히 Member만 가져오고(1), 즉시로딩 옵션이 있으면 추가로 Member 갯수(N)만큼 쿼리를 날려서 연관관계를 가져옴
  • (2) 연관관계를 한꺼번에 조회해야하는 경우가 있다면?
    • 모든 연관관계를 LAZY로 설정, 필요시 JPQL fetch join을 통해 데이터를 한번에 가져오는 방식으로 해결
  • @ManyToOne, @OneToOne은 기본이 즉시로딩 => 직접 LAZY로 설정 필요
  • @OneToMany, @ManyToMany는 기본이 지연로딩

0개의 댓글