[JPA] 프록시 객체의 초기화

  • member.getName() 같은 데이터가 필요한 경우 DB 조회하여 실엔티티 객체를 만듬
  • 해당 과정을 초기화하고 한다.
// 프록시 객체로 MemberProxy 반환
Member member = em.getReference(Member.class, "id1");
member.getName(); // getName() 호출 시 초기화 발생
// 프록시 클래스 예시 코드
class MemberProxy extends Member {
    Member target = null; // 진짜 엔티티 참조 변수

    public String getName() {
        if (target == null) {
            // 초기화 요청, DB 조회 후 진짜 엔티티 생성하고 참조 보관
            this.target = ...; // 초기화 로직 실행
        }
        return target.getName(); // 진짜 엔티티 getName 호출
    }
}

프록시 초기화 과정

  1. 프록시 객체 member.getName() 호출 -> 진짜 데이터 필요해짐.
  1. 프록시 객체 -> 엔티티 아직 생성 안 됐으면 영속성 컨텍스트에 만들어달라 요청 -> 초기화 시작.
  1. 영속성 컨텍스트 -> DB 조회해서 진짜 엔티티 객체 만듬.
  1. 프록시 객체 -> 만들어진 진짜 엔티티 객체 참조 Member target 변수에 저장.
  1. 프록시 객체 -> 저장된 진짜 엔티티 getName() 호출 -> 결과 받아서 반환.

프록시 객체 특성 이해

  • 단일 초기화
    • 프록시 객체는 사용될 때 한 번만 초기화
  • 프록시와 실제 엔티티 구분
    • 초기화된다고해서 프록시 객체는 실제 엔티티로 변하지 X
    • 초기화를 통해 실제 엔티티 접근
  • 타입 체크 주의
    • 프록시는 원본 엔티티를 상속받기에 타입 체크시 주의
  • 영속성 컨텍스트와 관계
    • 이미 영속성 컨텍스트에 엔티티가 존재한다면,
    • em.getReference() 호출시 실제 엔티티를 반환
  • 초기화의 제약
    • 프록시 객체의 초기화는 영속성 컨텍스트가 필요하므로 준영속 상태에서는 초기화 시 문제가 발생할 수 있다. 하이버네이트는 이런 경우 LazyInitializationException을 발생시킨다.


Uploaded by N2T