클라우드 낚시꾼

[JPA] JPA 프록시 개념 (getReference) 본문

BE Framework/JPA

[JPA] JPA 프록시 개념 (getReference)

KanuBang 2024. 5. 7. 16:29
728x90

1. find()와 getReference() 소개

Proxy 인스턴스

  • em.find(): 데이터베이스에서 엔티티 데이터를 즉시 로드한다. (즉시 로딩)
  • em.getReference(): 프록시 인스턴스를 제공하고 실제 엔티티 데이터의 로딩을 필요할 때까지 지연시킨다. (지연 로딩)

예제 코드

@Entity
public class Member {
    @Id
    private Long id;
    private String name;

    // getters and setters
}

EntityManager em = entityManagerFactory.createEntityManager();
// find() -> 즉시 로딩
Member member1 = em.find(Member.class, 1L);

// getReference() -> 지연 로딩
Member member2 = em.getReference(Member.class, 1L);

2. 프록시 특징

프록시의 특징

 

  1. 프록시 객체는 EntityManager의 getReference() 메소드를 통해 생성된다. 이 객체는 실제 엔티티 데이터를 담고 있지 않고, 실제 클래스를 상속받은 프록시 클래스의 인스턴스이다.
  2. 프록시 객체에 대한 첫 접근이 발생할 때, JPA는 필요한 데이터를 데이터베이스에서 로드하여 프록시 객체를 초기화한다.
  3. 프록시 객체는 실제 객체의 참조(target)를 보관한다.
  4. 프록시 객체를 호출하면 프록시 객체는 실제 객체의 메소드 호출한다.

3. 프록시 초기화 및 동작

프록시 동작

  • 프록시는 실제 엔티티를 대신하여 사용된다.
  • 프록시 뒤의 실제 엔티티는 엔티티의 속성에 접근할 때까지 로드되지 않는다.
  • 프록시는 실제 엔티티가 로드되면 호출을 실제 엔티티에 위임한다.
  • 엔티티 클래스 메소드가 프록시에서 호출될 때, 먼저 엔티티가 로드되었는지 확인한다. 그렇지 않다면 데이터베이스에서 엔티티를 가져옵니다.
// 프록시 위임

// ID는 이미 알려져 있기 때문에 프록시를 초기화하지 않습니다.
member2.getId();   

// 'name'은 프록시의 초기 데이터에 포함되지 않기 때문에 데이터를 로드하고 프록시를 초기화합니다.
member2.getName();

4. 결론

EntityManager em = entityManagerFactory.createEntityManager();
Member member = em.getReference(Member.class, "id1");
String memberName = member.getName();  // 'name'에 접근하면 DB 로드가 트리거됩니다.
  • getReference()는 find()와 달리 DB에서 즉시 전체 엔티티를 로드할 필요가 없이 지연로딩이 가능하다.
  • 프록시를 사용함으로써, JPA는 식별자만 필요한 경우 전체 엔티티를 로드하는 비용을 피할 수 있습니다.
  • 사용하는 입장에서는 진짜 객체인지 프록시 객체인지 구분하지 않고 사용하면 된다.
728x90