프록시
엔티티를 조회할 때 연관된 엔티티를 항상 사용하는 것은 아니다
데이터베이스에서 사용하지 않는 연관된 엔티티를 함께 조회하는 것은 효율적이지 않다
JPA는 이런 문제를 해결하기 위해 데이터베이스 조회를 실제 사용할 때까지 지연하는 방법을 제공하는데 이를 지연 로딩이라 한다
지연 로딩을 사용하기 위해서 실제 엔티티 객체 대신 데이터베이스 조회를 지연할 수 있는 가짜 객체가 필요한데 이를 프록시 객체라 한다
프록시 기초
EntityManager.find()를 사용해 조회하면 엔티티를 실제 사용하든 사용하지 않든 데이터베이스를 조회한다
엔티티를 실제 사용하는 시점까지 데이터베이스 조회를 미루려면 EntityManager.getReference() 메소드를 사용해야 한다
JPA는 데이터베이스를 조회하지 않고 실제 엔티티 객체도 생성하지 않는다
데이터베이스 접근을 위임한 프록시 객체를 반환한다
프록시의 특징
- 프록시 클래스는 실제 클래스를 상속받아 만들어져 실제 클래스와 겉 모양이 같다
- 사용하는 입장에서는 진짜 객체인지 프록시 객체인지 구분하지 않고 사용하면 된다
- 프록시 객체는 실제 객체에 대한 참조를 보관한다
프록시 객체의 초기화
프록시 객체는 실제 사용될 때 데이터베이스를 조회해 실제 엔티티 객체를 생성하는데 이를 프록시 객체의 초기화라 한다
프록시 초기화 과정
1. 프록시 객체에 member.getName()을 호출해 실제 데이터를 조회한다
2. 프록시 객체는 실제 엔티티가 생성되어 있지 않으면 영속성 컨텍스트에 엔티티 생성을 요청한다
3. 영속성 컨텍스트는 데이터베이스를 조회해 실제 엔티티 객체를 생성한다
4. 프록시 객체는 생성된 실제 엔티티 객체의 참조를 보관한다
5. 프록시 객체를 실제 엔티티 객체의 getName()을 호출해 결과를 반환한다
프록시 객체의 특징
프록시 객체는 처음 사용할 때 한 번만 초기화된다
프록시 객체를 초기화한다고 프록시 객체가 엔티티로 바뀌는 것이 아니라 프록시 객체를 통해 실제 엔티티에 접근할 수 있게 된다
프록시 객체는 원본 엔티티를 상속받은 객체로 타입 체크 시 주의해서 사용해야 한다
영속성 컨텍스트에 찾는 엔티티가 이미 있으면 데이터베이스를 조회할 필요가 없으므로 프록시 객체를 호출해도 실제 엔티티를 반환한다
초기화는 영속성 컨텍스트의 도움을 받아야 가능하다
- 영속성 컨텍스트의 도움을 받을 수 없는 준영속 상태의 프록시를 초기화하면 문제가 발생한다
- LazyInitializationException 예외를 발생시킨다
프록시와 식별자
엔티티를 프록시로 조회할 때 식별자 값을 전달하는데 프록시 객체는 이 값을 보관한다
식별자 값을 조회하는 메서드를 호출하더라도 프록시를 초기화하지 않는다
- 엔티티 접근 방식을 프로퍼티로 설정한 경우에만 초기화하지 않는다
- 엔티티 접근 방식을 필드로 한 경우에는 JPA가 getId()가 식별자만 조회하는 메소드인지 다른 필드까지 활용을 하는 메소드인지 알 수 없으므로 프록시 객체를 초기화한다
연관관계를 설정할 때에는 식별자 값만 사용하므로 프록시를 이용하면 데이터베이스 접근 횟수를 줄일 수 있다
- 연관관계 설정 시에는 엔티티 접근 방식을 필드로 설정해도 프록시를 초기화하지 않는다
프록시 확인
JPA가 제공하는 메소드를 사용해 프록시 인스턴스의 초기화 여부를 확인할 수 있다
boolean isLoad = em.getEntityManagerFactory().getPersistenceUnitUtil().isLoaded(entity);
//boolean isLoad = emf.getPersistenceUnitUtil().isLoaded(entity);
조회한 엔티티의 클래스 명을 조회해 초기화 여부를 확인할 수 있다
- 클래스 명 뒤에 javassist라 되어있으면 프록시이다
'스터디 > JPA' 카테고리의 다른 글
프록시와 연관관계 정리 - (3) (1) | 2025.02.14 |
---|---|
프록시와 연관관계 정리 - (2) (0) | 2025.02.13 |
고급 매핑 - (3) (0) | 2025.02.12 |
고급 매핑 - (2) (0) | 2025.02.12 |
고급 매핑 - (1) (0) | 2025.02.11 |