프록시와 연관관계 관리
프록시
@Enitity
public class Member {
private String username;
@ManyToOne
private Team team;
...
}
- 지연로딩(lazy loading)이란 엔티티가 사용될때 까지 데이터베이스에서 조회를 지연하는 것
- 사용전까지 가짜 객체가 대신하는데 이를 프록시 객체라고 함
프록시 기초
find()
는 영속성 컨텍스트에 엔티티가 없으면 사용여부와 관계없이 데이터베이스를 조회getReference()
는 데이터베이스를 조회하지 않고 엔티티 객체도 생성하지 않음, 데이터베이스 접근을 위임한 프록시 객체를 반환
// 즉시 조회
Member member = em.find(Member.class, "member1");
// 지연 조회
Member member = em.getReference(Member.class, "member1");
- 프록시 객체는 처음 사용할 때 한 번만 초기화
- 프록시 객체는 실제 객체에 대한 참조를 보관
- 프록시 객체를 통해 실제 엔티티에 접근 가능
- 프록시는 실제 클래스를 상속받아서 만들어짐
- 사용하는 입장에서는 진짜 객체인지 프록시 객체인지 구분하지 않음
- 타입 체크시 주의
- 접근할 엔티티가 영속성 컨텍스트에 존재하면 데이터베이스 조회하지 않고 실제 엔티티 반환
- 초기화는 영속성 컨텍스트의 도움을 받아야 가능
- 영속성 컨텍스트의 도움을 받을 수 없는 준영속 상태의 프록시를 초기화하면
org.hibernate.LazyInitializationException
예외 발생- JPA 표준 명세는 지연 로딩(프록시)에 대한 내용을 JPA 구현체에 맡김
- 따라서 준영속 상태의 엔티티를 초기화할때 어떤일이 발생할지에 대한 표준이 없음
- 위 예외는 하이버네이트 사용시 발생
- 영속성 컨텍스트의 도움을 받을 수 없는 준영속 상태의 프록시를 초기화하면
// 프록시 반환
Member member = em.getReference(Member.class, "member1");
transaction.commit();
em.close(); // 영속성 컨텍스트 종료
member.getName(); // 준영속 상태에서 초기화 시도, 예외 발생