JPA

[JPA] 프록시

딤섬뮨 2022. 7. 28. 23:11
728x90
  • 글을 이해하기 위한 지식 - 영속성 컨텍스트

실제로 잘 안 쓰이기는 개념이기는 하지만 나중에 지연 로딩을 위해 알아본다.

예를 들어 Member Entity안에 Name, Team 필드가 있는데 

Member의 Name을 조회할 때 굳이 Team도 함께 조회해야 할까?

즉 member객체를 전체 가져오고 그 안에서 member.getTeam()을 꼭 해야 할까?

 

아니다 꼭 다 가져올 필요는 없다 이걸 프록시로 해결한다.

 

프록시 기초

  • 데이터베이스 조회를 미루는 가짜 엔티티 객체

em.getReference를 사용하면 호출한 시점에는 쿼리가 안 나가고(member 객체 전체를 불러오지 않고) 사용되는 시점(em.getUserName)에 쿼리가 나간다.

 

실제 클래스를 상속받아서 만들어지며 프락시 객체는 실제 객체의 참조(target)를 보관한다.

 

  1. 사용자가 getName()을 요청하면
  2. Mmeber target값이 없으니 영속성 컨텍스트에 요청(초기화 요청)
  3. 실제 객체를 생성해서 주면
  4. 실제 객체를 target과 연결함.
Member member = em.getReference(Member.class,member1.getId()); // 아직 프록시만 만들어짐
refMember.getUsername(); //프록시 안에 실제 객체가 들어감

 

프록시의 특징

  • 프록시 객체는 처음 사용할 때 한번만 초기화
  • 프록시 객체를 초기화 할 때 프록시 객체가 실제 엔티티로 바뀌는 것이 아님.
  • 프록시로 넘어올지 엔티티로 넘어올지 모르기에 == 비교로 하지 말기
  • 영속성 컨텍스트에 이미 찾는 엔티티가 있으면 em.getReference해도 객체가 들어옴
  • 프록시를 한번 반환하면 그 이후에 find해도 프록시를 반환하게 됨.
  • 프록시가 아니든 프록시든 문제가 없게 개발하는 것이 중요함.

그런데 만약 초기화해야 하는 영속성 콘텍스트가 없는 상황이 돼버리면?

 

error - og.hibernaete.LazyInitiaizationException

 

고로 프록시를 사용하려면 영속성 컨텍스트 꼭 있어야 함.

 

프록시 확인

 

초기화 여부 확인 

 

- 프록시 인스턴스 초기화 여부 확인

PersistenceUnitUtil.isLoaded(Object entity)

- 프록시 클래스 확인 방법 

entity.getClass().getName()

- 프록시 강제 초기화(하이버네이트 제공)

org.hibernate.Hibernate.initialize(entity);

(참고) JPA 표준은 강제 초기화 없음 member.getName()으로 초기화해야 함

 

 

 

출처 - 인프런 김영한 JPA 기본 강의

728x90

'JPA' 카테고리의 다른 글

연관관계에 관한 다양한 생각들(+지양해야할것)  (0) 2022.11.17
[JPA] 값 타입과 불변 객체  (0) 2022.08.02
[JPA] 지연 로딩(Lazy Loading)  (0) 2022.07.29