목표
Jpa 즉시로딩과 지연로딩의 개념에 대해 알아보자. 즉시로딩과 지연로딩의 개념을 이해하기 위해서는 Jpa Proxy 객체 개념의 이해가 선행되어야 한다. Proxy에 대한 이해가 없다면 JPA Proxy란? 을 먼저 보면 좋을 것 같다.
즉시로딩(EAGER)과 지연로딩(LAZY)
즉시로딩(EAGER Loading)
Hibernate는 지연로딩과 즉시로딩, 두 가지 로딩 전략을 제공하는데, 즉시로딩은 연관된 엔티티를 한 번의 쿼리로 함께 로딩하는 방식을 말한다. 즉시로딩을 사용하면, Entity와 연관된 모든 Entity들이 한 번에 로딩되므로, 필요한 데이터를 즉시 사용할 수 있다. 연관관계 annotation 속성에 "fetch = FetchType.EAGER"를 추가하여 사용할 수 있다.
예를 들어, 위와 같이 B와 OneToOne의 연관관계를 가지고 있는 A가 있다고 할때 즉시로딩을 사용해 A를 조회하게 된다면 A와 연관된 B도 함께 로딩될 것이다. 테스트 코드와 결과를 살펴보면 실제로 A를 조회하였지만 DB 요청 쿼리는 B까지 함께 요청하고 있다.
즉시로딩은 데이터베이스의 성능에 영향을 줄 수 있다는 문제점이 있다. 즉시로딩을 사용하면 필요하지 않은 Entity들까지 함께 로딩되므로, 데이터베이스에 추가적인 부하가 발생할 수 있으며 깊은 계층의 연관된 엔티티들이 많을 경우 무한루프에 빠질 수 있고 성능 저하가 발생할 수 있다. 실무에서는 가급적 지연로딩만 사용하길 권장한다고 한다. 즉시로딩을 적용하면 예상하지 못한 SQL이 발생하고 즉시로딩은 JPQL에서 N+1 문제를 일으킨다. ManyToOne, OneToOne은 기본이 즉시 로딩이니 LAZY로 설정을 바꿔서 사용하도록 하자.
지연로딩(LAZY Loading)
지연로딩은 연관된 Entity를 한번에 로딩하지 않고 추후, 필요한 시점에 로딩하는 방식을 의미한다. 연관된 Entity는 초기 Proxy 객체로 생성되며, Entity를 실제로 사용하는 시점에 데이터베이스에 조회 요청을 보내 필요한 정보를 로딩한다. 지연로딩을 사용하면 필요한 연관 Entity만 로딩하므로 성능상의 이점을 얻을 수 있다. 연관관계 annotation 속성에 "fetch = FetchType.LAZY"를 추가하여 사용할 수 있다.
지연로딩을 사용하면 앞서 다뤘던 즉시로딩과 다르게 A와 B가 연관관계를 가지고 있다고 하더라도 A를 조회할때 B가 같이 로딩되지 않는다. 지연로딩의 동작은 Proxy를 기반으로 한것이기 때문에 Proxy사용시 주의점을 잘 익히고 사용하도록 하자.
[ 참고자료 ]
https://www.inflearn.com/course/ORM-JPA-Basic/dashboard