[JPA] 프록시

19·2022년 10월 14일
0

JPA

목록 보기
11/18

프록시

실제 클래스를 상속받아서 만들어진다.
실제 클래스와 겉모양이 같다.
사용하는 입장에서는 진짜 객체인지, 프록시 객체인지 구분하지 않고 사용하면 된다.
프록시 객체는 실제 객체의 참조(target)을 보관한다.
프록시 객체를 호출하면 프록시 객체는 실제 객체의 메소드를 호출한다.



em.find()

  • 데이터베이스를 통해서 실제 엔티티 객체를 조회

em.getReference()

  • 데이터베이스 조회를 미루는 가짜(프록시) 엔티티 객체 조회
  • 실제 사용되는 시점에 데이터베이스에 쿼리를 날림

  • getReference()를 통해 가져온 객체는, 껍데기는 똑같지만 안에는 비어있다.
  • target이 진짜 레퍼런스를 가리킨다.

사용예시)

Member member = em.getReference(Member.class, 1L);
member.getName();
  • member는 프록시 객체
    • getName()을 호출하면, 실제 엔티티 객체의 메소드를 호출한다. (target에 실제 객체 참조 저장)
    • 그런데 현재 target에는 값이 없다 (null)
    • 영속성 컨텍스트에 실제 엔티티 객체를 요청한다.
      • 영속성 컨텍스트는 DB를 조회하고 실제 엔티티 객체를 생성한다.
      • 프록시 객체의 target과 실제 엔티티 객체를 연결한다.
    • 이제 getName()을 호출하면 실제 엔티티 객체의 메소드를 호출한다.

  • 프록시 객체는 처음 사용할 때 한 번만 초기화한다
  • 타입 체크 시, '==' X, instanceof 사용
  • 영속성 컨텍스트에 찾는 엔티티가 있다면, getReference()를 호출해도 실제 엔티티가 반환된다.
  • 만약 준영속 상태라면? -> 프록시 초기화 시 에러가 발생 (org.hibernate.LazyInitializationException)



참고

자바 ORM 표준 JPA 프로그래밍 - 기본편 - 김영한

profile
하나씩 차근차근

0개의 댓글