JPA 프록시란?

정체는 김태현·2022년 10월 31일
0

항해99

목록 보기
36/38

프록시

Member 엔티티를 조회할 때 불필요하게 team까지 조회를 계속하게 되면 DB 성능에 영향을 미치게 된다.
Member만 조회할 수 있게 JPA에서는 지연 로딩과 프록시라는 개념을 사용한다.

entityManager.find()

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

entityManager.getReference()

데이터베이스 조회를 통하지 않고 프록시 엔티티 객체 반환

실제 사용시에 DB를 조회해서 실제 Entity 생성(프록시 객체 초기화) ex. member.getUsername()

  • JPA 표준은 강제 초기화가 없기에 강제 호출 -> member.getName()과 같이 강제 초기화
  • em.find()는 DB를 통해서 실제 엔티티 객체를 조회하는 메서드 -> 즉 DB까지 직접 접근

  • em.getReference()는 DB까지 접근하지 않고 프록시 엔티티 객체를 조회하는 메서드

  • em.getReference()로 조회를 하면 실제로 필요한 시점에 데이터베이스에 쿼리가 나간다.

  • getClass()로 객체를 확인하면 HibernateProxy 객체이다.

프록시 특징

  • 실제 클래스를 상속 받아서 만들어짐

  • 실제 클래스와 겉모양이 같음

  • 사용하는 입장에서는 진짜 객체인지 프록시 객체인지 구분하지 않고 사용하면 됨

  • 프록시 객체는 실제 객체의 참조(target)를 보관

  • 프록시 객체 호출하면 실제 target의 메소드 호출

  • 처음 사용할 때 한 번만 초기화

  • 프록시 객체 초기화 : 프록시가 실제 엔티티가 되는 것이 아니라 실제 엔티티(target)에 접근 가능해짐

  • 프록시 객체는 원본 엔티티 상속 받음

    • 실제 엔티티와 프록시 객체는 == 비교 시 false. instance of 로 비교해야함
  • 영속성 컨텍스트에 찾는 엔티티가 이미 있으면 entityManager.getReference()를 호출해도 실제 엔티티 반환

  • find(), getReference() : 엔티티에 처음 담긴 값을 반환

    • 처음에 실제 엔티티 객체가 담겼으면 실제 엔티티 객체를, 프록시 객체가 담겼으면 프록시 객체를 반환
  • org.hibernate.LazyInitializationException: could not initialize proxy

    • 준영속 상태일 때 프록시를 초기화하면 예외 발생




출처
https://allonsyit.tistory.com/106
https://blog.naver.com/fbfbf1/222676528942

profile
하나부터 열가지 다

0개의 댓글