spring boot/JPA - 기본

JPA - proxy(프록시)

ballde 2021. 11. 13. 23:48
printMember(Member member) {
    member.getUsername();

  // username만 가져오면 되는데 team 정보도 가져오면 성능상 손해
}
printMemberAndTeam(Member member) {
    member.getTeam();
    member.getUsername();
}

지연로딩, 프록시로 해결 가능
프록시
em.getReference() - 데이터베이스 조회를 미루는 가짜(프록시) 엔티티 객체 조회
초기화 할 때는 sql 이 생성 안되고 
아래처럼 사용 될 경우 호출함
System.out.println("findMember.username = " + findMember.getUsername());

proxy가 값을 가지고 있으면 그 proxy객체에서 반환

없으면 초기화 요청 → db조회 → proxy와 db조회한 Member연결

프록시의 특징

  • 프록시 객체는 처음 사용할 때 한번만 초기화
  • 프록시 객체가 실제 엔티티로 바뀌는 것이 아님, 초기화 되면 실제 엔티티에 접근 가능
  • 원본 엔티티 상속 -> 타입 체크시 주의(== 비교 X, 대신 instance of 사용)
  • 영속성 컨텍스트에 찾는 엔티티가 이미 있으면 em.getReference()를 호출해도 실제 엔티티 반환
  • 처음에 em.getReference를 호출하고 em.find하면 em.find도 프록시가 된다.
  • 영속성 컨텍스트의 도움을 받을 수 없는 준영속 상태일 때, 프록시를 초기화하면 문제 발생
  • could not initialize proxy ... 오류 뜸
Member member = em.getReference(Member.class, member1.getId());

em.detach(member);
em.close();
// 영속성이 더이상 관리를 안하게 되서 오류남

member.getUsername();
프록시 인스턴스의 초기화 여부 확인
PersistenceUnitUtil.isLoaded(Object entity) -> emf.PersistenceUnitUtil.isLoaded(findMember)
프록시 클래스 확인 방법
findMember.getClass()
프록시 강제 초기화
Hibernate.initialize(findMember);

'spring boot > JPA - 기본' 카테고리의 다른 글

JPA - cascade, orphanRemoval  (0) 2021.11.21
JPA - 상속관계 매핑  (0) 2021.11.08
JPA - 연관관계 매핑(2)  (0) 2021.11.08
JPA - 연관관계 매핑  (0) 2021.10.26
jpa - 엔티티 매핑  (0) 2021.10.21