hoondev

[Spring JPA] 프록시 본문

Spring JPA

[Spring JPA] 프록시

hoondev3 2023. 2. 1. 18:21

프록시

jpa에서 em.getReference()를 사용하면 데이터베이스의 조회를 미루는 프록시 엔티티를 조회할 수 있다.

 

프록시의 특징

  • 실제 클래스를 상속 받아서 만들어짐
  • 실제 클래스와 겉 모양이 같다
  • 사용하는 입장에서는 진짜 객체인지 프록시 객체인지 구분하지 않고 사용하면 됨(이론상)
  • 프록시 객체는 실제 객체의 참조(target)를 보관
  • 프록시 객체를 호출하면 프록시 객체는 실제 객체의 메소드 호출
Member member = em.getReference(Member.class, “id1”); 
member.getName();

getName() 메서드를 호출할때 다음과 같은 일이 벌어진다.

 

getName()을 호출하면 프록시 객체의 target을 조회한 후 null이면 영속성 컨텍스트 초기화를 요청한다.

영속성 컨텍스트는 DB를 조회해서 실제 엔티티를 생성한다. 프록시 객체는 생성된 실제 엔티티 참조하기 때문에 target.getName()을 수행하여 실제 엔티티의 name을 반환하게 된다.

 

프록시 초기화 특징

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

프록시 확인

  • 프록시 인스턴스의 초기화 여부 확인: PersistenceUnitUtil.isLoaded(Object entity) 
  • 프록시 클래스 확인 방법: entity.getClass().getName() 출력(..javasist.. or HibernateProxy…) 
  • 프록시 강제 초기화: org.hibernate.Hibernate.initialize(entity);
  • (참고) JPA 표준은 강제 초기화 없음 강제 호출: member.getName()

Reference

https://www.inflearn.com/course/ORM-JPA-Basic

'Spring JPA' 카테고리의 다른 글

[Spring JPA] 영속석 전이와 고아객체  (0) 2023.02.03
[Spring JPA] 즉시 로딩과 지연 로딩  (1) 2023.02.02
[Spring JPA] @MappedSuperclass  (0) 2023.01.31
[Spring JPA] 상속관계 매핑  (0) 2023.01.30
[Spring JPA] 다대다 관계  (0) 2023.01.29
Comments