프록시

Member를 조회할 때 Team도 함께 조회가 되는데 비효율적이지않나?

프록시1


프록시 기초


  • em.find() vs em.getReference()
  • em.find() : 데이터베이스를 통해서 실제 엔티티 객체를 조회하게된다.
  • em.getReference() : 데이터베이스 조회를 미루는 가짜(프록시) 엔티티 객체를 조회한다.


프록시 특징


  • 프록시 객체는 처음 사용할 때 한번만 초기화한다.
  • 프록시 객체를 초기화 할 때, 프록시 객체가 실제 엔티티로 바뀌는것이 아니라 초기화되면 실제 엔티티에 접근이 가능한것임
  • 프록시 객체는 원본 엔티티를 상속받음, 따라서 타입 체크시 == 비교 대신, instance of 사용
  • 영속성 컨텍스트에 찾는 엔티티가 이미 있으면 em.getReference() 호출해도 실제 엔티티 호출 ( 이 반대도 성립 )
  • 영속성 컨텍스트의 도움을 받을수 없는 준영속 상태일때, 프록시를 초기화 할 때 문제발생
  • ( 하이버네이트는 org.hibernate.LazyInitializationException 예외를 터트림 )
  • 프록시 객체는 실제 객체의 참조(target)를 보관한다.
  • 프록시 객체를 호출하면 프록시 객체는 실제 객체의 메소드를 호출한다.

프록시2


프록시 객체의 초기화


Member member = em.getReference(Member.class, "id1");
member.getName();

위 코드 실행시.. 프록시3


  • 위 사진에서 알 수 있는것은 영속성 컨텍스트를 닫거나 준영속성 컨텍스트 상태라면 프록시 초기화에 문제가 발생한다.

프록시 확인

  • 프록시 인스턴스의 초기화 여부 확인
    • PersistenceUnitUil.isLoaded(Obejct entity)
  • 프록시 클래스 확인 방법
    • entity.getClass().getName() 출력
  • 프록시 강제 초기화
    • org.hibernate.Hibernate.initialize(entity)
  • 강제 호출 : member.getName() 식으로 진행, JPA 표준은 강제 초기화없음


😄 참고 : 인프런 김영한님의 JPA 기본 강의 및 교재

🌜 개인 공부 기록용 블로그입니다. 오류나 틀린 부분이 있을 경우 언제든지 댓글 혹은 메일로 지적해주시면 감사하겠습니다! 😄

개인메모

태그:

카테고리:

업데이트: