본문 바로가기

JPA

프록시와 지연/즉시 로딩

1. 프록시

  • em.find() vs em.getReference()
  • em.find() : 데이터베이스를 통해 실제 엔티티 객체를 조회
  • em.getReference() : 데이터베이스 조회를 미루는 가짜(프록시) 엔티티 객체를 조회

프록시 초기화

  • 실제 클래스를 상속 받아서 만들어짐
  • 겉 모양이 같음
  • 실제 객체의 참조를 보관
  • 요청 -> 초기화 확인 -> 영속성 컨텍스트 통해 DB 조회 -> 실제 엔티티 생성 -> 프록시 연결

특징

  • 객체는 처음 사용할 때 한번만 초기화
  • 초기화시 프록시 객체가 실제 엔티티로 바뀌는 것이 아니라 참조하여 실제 엔티티에 접근
  • 실제 인티티를 상속 받으므로 (== 비교 실패, instance of 사용)
  • 영속성컨텍스트에 찾는 엔티티가 있으면 em.gerRefence()를 호출해도 실제 엔티티 반환 : 한 트랜잭션 안에서는 동일성을 보장하는 JPA의 특성
  • 준영속 상태일 때는 조회가 되지 않고 예외가 발생

확인

//프록시 초기화 확인
 User infoProxy = em.getReference(User.class, user1.getId());
 System.out.println("emf.getPersistenceUnitUtil().isLoaded(infoProxy) = "
 + emf.getPersistenceUnitUtil().isLoaded(infoProxy));

//클래스 확인
System.out.println("infoProxy.getClass() = " + infoProxy.getClass().getName());

//프록시 강제 초기화
 Hibernate.initialize(infoProxy);
//JPA 표준은 강제 초기화 없음
                    
                    

 

 

2. 즉시로딩 과 지연로딩

 

지연로딩

  • 연관관계가 맺어진 객체끼리 서로 참조가 낮을 때
  • lazy를 통해 프록시로 조회 -> 지연 로딩

 

즉시로딩

  • 연관관계가 맺어진 객체끼리 참조가 높을 때, 호출시에 join을 통해 다 가지고 옴
  • eager를 통해 실제 엔티티로 조회 -> 즉시로딩
  • 실무에서 비추천, 예상치 못한 SQL 발생, JPQL에서 N+1문제를 발생
  • ManyToOne, OneToOne 어노테이션 default값은 즉시로딩이기 때문에 Lazy로 설정

 

** N+1 문제 : jpql 에서 연관관계가 있는 테이블에 대해 추가로 sql을 날림

** lazy로 사용하고 join fetch나 엔티티 그래프 기능을 사용하여 해결

'JPA' 카테고리의 다른 글

값 타입  (0) 2023.03.27
영속성전이와 고아객체  (0) 2023.02.20
상속관계 매핑  (0) 2023.02.06
연관관계의 종류  (0) 2023.01.18
연관관계 매핑  (0) 2023.01.04