JPA. 프록시와 지연로딩

무지성개발자·2024년 2월 19일
0

JPA

목록 보기
8/12

JPA 프록시 객체

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객체는 초기화를 해도 프록시 객체라는 것이다.

프록시 객체 특징

  • 프록시 객체는 처음 사용할 때 한 번만 초기화
  • 프록시 객체를 초기화 해도 실제 엔티티로 바뀌지 않음.
    • 위 예제와 같은 상황.
    • 실제 엔티티에 접근이 가능해진 프록시 객체인 것.
  • 프록시 객체는 원본 엔티티를 상속 받은 것이니 타입체크 주의
    • == 동등성 비교로 하면 안됨.
    • instance of로 타입 체크
  • 영속성 컨텍스트 특징 중 하나인 동일성 보장 때문에 em.getReference()를 호출해도 실제 엔티티 반환 될 수 있음.
    • em.find()로 실제 엔티티를 영속성 컨텍스트에 담아뒀다면 em.getReference()도 실제 엔티티 반환
    • em.getReference()로 프록시 객체를 영속성 컨텍스트에 담아뒀다면 em.find()도 프록시 객체를 반환.
  • 준영속 상태일 때, 프록시 초기화 하면 LazyInitializationException.

즉시 로딩과 지연 로딩

위 프록시 객체의 경우 지연로딩에서 자주 사용된다.

Member 엔티티와 Team엔티티가 @ManyToOne으로 관계를 맺고 있다고 가정해보자.

즉시 로딩

즉시 로딩은 관계를 맺고 있는 엔티티를 모두 한번에 불러오는 것을 말한다. @XXToOne의 경우 기본값이다.

예를 들어 Member 엔티티를 초기화 할 때 해당 member의 team도 가져와야 하기 때문에 Team 엔티티를 바로 초기화.

지연 로딩

지연 로딩은 관계를 맺고 있는 엔티티를 사용하는 시점에 불러오는 것을 말한다. @XXToMany의 경우 기본값이다.

예를 들어 Member 엔티티를 초기화 할 때 Team 객체는 프록시 객체를 사용하다가 Team 객체를 사용 할 때 DB에 접근해 초기화 한다.

결론

프록시 객체는 사용을 안하면 구지 안가져 와도 된다는 철학에서 나온 것으로 보인다. 김영한님의 강의 또는 책을 읽어보면 실무에서는 여러 이유 때문에 지연 로딩만 사용하는 것을 권장한다.

profile
no-intelli 개발자 입니다. 그래도 intellij는 씁니다.

0개의 댓글