JPA는 프록시 객체를 반환하기도 하는데 프록시 객체는 가짜 엔티티로 엔티티의 사용시점에 DB에 접근하여 실체 객체를 가져와 사용한다.
프록시 객체는 em.getReference()로 만들며 초기화 시점은 엔티티 사용 시점이다.
Member findMember = em.getReference(Member.class, member.getId());
System.out.println("findMember type = " + findMember.getClass());
System.out.println("=============================================");
System.out.println("findMember = " + findMember.getName()); // 초기화 시점
System.out.println("=============================================");
System.out.println("findMember type = " + findMember.getClass());
위 코드를 실행하면 다음 이미지와 같은 결과를 얻는다.
여기서 중요한건 findMember객체는 초기화를 해도 프록시 객체라는 것이다.
위 프록시 객체의 경우 지연로딩에서 자주 사용된다.
Member 엔티티와 Team엔티티가 @ManyToOne으로 관계를 맺고 있다고 가정해보자.
즉시 로딩은 관계를 맺고 있는 엔티티를 모두 한번에 불러오는 것을 말한다. @XXToOne의 경우 기본값이다.
예를 들어 Member 엔티티를 초기화 할 때 해당 member의 team도 가져와야 하기 때문에 Team 엔티티를 바로 초기화.
지연 로딩은 관계를 맺고 있는 엔티티를 사용하는 시점에 불러오는 것을 말한다. @XXToMany의 경우 기본값이다.
예를 들어 Member 엔티티를 초기화 할 때 Team 객체는 프록시 객체를 사용하다가 Team 객체를 사용 할 때 DB에 접근해 초기화 한다.
프록시 객체는 사용을 안하면 구지 안가져 와도 된다는 철학에서 나온 것으로 보인다. 김영한님의 강의 또는 책을 읽어보면 실무에서는 여러 이유 때문에 지연 로딩만 사용하는 것을 권장한다.