em.getReference()를 통해 호출 가능
그렇다면 em.find()와 다른 점은?
em.find()는 데이터베이스를 통해서 실제 엔티티 객체를 조회. 반면 em.getReference()는 조회를 곧바로 하는 것이 아닌 프록시에다가만 조회 해놔서 미뤄 놓은 상태!
프록시 객체는 처음 사용할 때 한번만 초기화.
초기화 할 때, 실제 엔티티로 바뀌는 것은 아니며 프록시 객체를 통해서 실제 엔티티에 접근을 하는 것!
만일, 영속성 컨텍스트에 실제 Entity가 있다면 getReference()를 활용하여도 실제 Entity를 반환하게 됨
이와 같은 테이블의 연관관계가 설정 되었다고 생각하여 봅시다
의문 . Member를 조회할 때 Team도 함께 조회?
@ManyToOne(fetch = FetchType.LAZY)
지연로딩이란 즉 위의 상황에서 Member조회 시, Team Entity는 프록시를 활용하여 바로 조회하는 것이 아닌 프록시를 만들어 놓는 것을 말합니다.
프록시를 설명하며 말했듯이 실제 team Entity를 사용하는 시점에서 프록시는 실제 Entity를 초기화 합니다.
ex) team.getName(); 과 같은 코드를 활용한 경우
@ManyToOne(fetch = FetchType.EAGER)
즉시로딩이란 Member 조회 시, Team Entity도 바로 조회하는 상황을 말합니다.
즉시로딩을 사용하면 안되는 젤 중요한 이유!
하나의 Entity를 조회하기 위해 날린 JPQL이 N개의 JPQL을 초래하게 되므로 N+1문제라고 합니다.
위의 상황에 놓여있는 연관관계에서 Member와 Team 은 N:1 매핑 관계 상태입니다.
여기서 Member객체를 조회할 때 즉시로딩을 사용한다고 생각하여 봅시다!
Team 객체를 바로 조회를할 것 입니다.
즉, Member Entity만 조회하기 위하여 SELECT문을 날렸는데 관련되어 있는 Team Entity를 모두 조회하기위해 관련되어 있는 Team Entity에 대하여 SELECT문을 다 날리는 상황을 초래합니다. 이는 성능 저하를 이끌게 되죠!
모든 연관관계에 지연 로딩!
이 글은 인프런 김영한님의 '자바 ORM 표준 JPA 프로그래밍 - 기본편'을 수강하고 작성합니다.
출처:https://www.inflearn.com/course/ORM-JPA-Basic