보다 더 나은 내일의 나를 위해

즉시로딩(EAGER)과 지연로딩(LAZY) 본문

spring/jpa

즉시로딩(EAGER)과 지연로딩(LAZY)

H-SC 2022. 4. 27. 12:54

JPA에서는 객체를 DB에서 찾아올 때의 방식을 위한 즉시 로딩지연 로딩 옵션 중 하나를 설정해 줄 수 있습니다.

@ManyToOne의 기본값은 즉시 로딩이고, @ManyToMany의 기본값은 지연 로딩으로 되어있습니다.

이 두 옵션은 무슨 차이가 있을까요?

 

 

즉시 로딩 : 즉시 로딩은 DB에서 엔티티를 찾아올 때 연관관계를 맺고 있는 엔티티들을 한 번에 바로 조회합니다.

 

지연 로딩 : 지연 로딩은 DB에서 엔티티를 찾아올 때 연관관계를 맺고 있는 엔티티들은 프록시 객체를 할당해 주어 나중에 실제로 사용할 때 따로 조회를 시도합니다.

 

코드를 통해 한번 알아봅시다.

우선 사용할 엔티티 구조입니다.

Human과 Organism은 서로 1 : N 관계입니다. 이때 fetch의 기본 값은 즉시 로딩(EAGER)으로 설정되어 있습니다.

 

Human

@Entity
public class Human {
    @Id @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "human_id")
    private Long id;
    
    @Column
    private String name;
    
    @ManyToOne(fetch = FetchType./* 로딩 설정 */)
    @JoinComumn(name = "organism_id")
    private Organism organism;
    
    ... Getter

}

 

Organism

@Entity
public class Organism {
    @Id @GeneratedValue(strategy = GeneratioinType.AUTO)
    @Column(name = "organism_id")
    private Long id;
    
    @Column
    private String kind;
    
    @Column
    private String name;
    
    @OneToMany(mappedBy = "organism")
    private List<Human> humans = new ArrayList<>();
    
    ... Getter
    
    }

 

또한 테스트를 위한 함수도 만들어봅시다.

 

테스트용

@Transactional(readOnly = true)
public void findHuman(Long id) {
    Human human = humanRepository.findById(id).orElseThrow);
    
    System.out.println("찾아옴");
    System.out.println(human);
    System.out.println(human.getOrganism());
}

 

마지막으로 sql을 보기 위해 application 파일을 설정해줍니다.

 

application.properties

# DB 설정
spring.jpa.properties.hibernateformat_sql=true

application.yaml

spring:
	DB 설정
    jpa:
    	prperties:
        	hibernate:
            	format_sql: true

 

 

즉시 로딩(EAGER)

우선 즉시 로딩의 동작 방식을 알아봅시다.

select
    human0_.idx as idx1_0_0_,
    human0_.name as name2_0_0_,
    human0_.organism_id as organism3_0_0_,
    organism1_.idx as idx1_1_1_,
    organism1_.kind as kind2_1_1_,
    organism1_.name as name3_1_1_ 
from
    human human0_ 
left outer join
    organism organism1_ 
        on human0_.organism_id=organism1_.idx 
where
    human0_.idx=?

찾아옴

Human@658098a2

Organism@2190508d

이처럼 Human을 조회할 때 Organism까지 한번에 조회합니다.

 

 

 

지연로딩(LAZY)

지연 로딩일때는 어떻게 동작할까요?

한번 실행시켜봅시다.

select
    human0_.idx as idx1_0_0_,
    human0_.name as name2_0_0_,
    human0_.organism_id as organism3_0_0_ 
from
    human human0_ 
where
    human0_.idx=?

찾아옴

Human@50628080

select
    organism0_.idx as idx1_1_0_,
    organism0_.kind as kind2_1_0_,
    organism0_.name as name3_1_0_ 
from
    organism organism0_ 
where
    organism0_.idx=?

Organism@7167d81b

지연 로딩으로 설정하면 처음엔 우선 Human만 조회합니다.

이때 Human과 연관관계를 맺고 있는 Organism은 프록시 객체가 들어가 있습니다.

이후에 Organism을 조회하려고 할 때 DB에서 조회해 객체를 보여주게 됩니다.

'spring > jpa' 카테고리의 다른 글

JPA의 Open-In-View란?  (0) 2022.04.26
Comments