자바 ORM 표준 JPA 프로그래밍 공부 기록
프록시를 사용하면 연관된 객체를 처음부터 데이터베이스에서 조회하는 것이 아니라 실제 사용하는 시점에 데이터베이스에서 조회할 수 있따. 자주 사용하는 객체들은 조인을 사용하여 함께 조회하는 것이 효과적일 수도 있다. JPA는 즉시 로딩
과 지연 로딩
으로 이 둘을 모두 지원한다.
엔티티를 조회 할 때 연관된 엔티티들이 항상 사용되는 것은 아니다. 비즈니스 로직에 따라 연관된 엔티티가 사용될 때도, 그렇지 않을 때도 있다.
JPA는 이런 문제를 해결하기 위해 엔티티가 실제 사용될 때 까지 DB 조회를 지연하는 방법을 제공하는데 이것을 지연 로딩
이라고 한다.
지연 로딩을 사용하려면 실제 엔티티 객체 대신에 DB를 조회를 지연할 수 있는 가짜 객체가 필요한데 이를 프록시 객체
라 한다.
em.find()
vs em.getReference()
em.find()
: 엔티티 조회. 영속성 컨텍스트에 엔티티가 없다면 DB를 조회em.getReference()
: DB를 조회하지 않고 실제 엔티티 객체 생성 X. DB 접근을 위임한 프록시 객체 반환Member findMember = em.getReference(Member.class, m.getId());
//System.out.println(findMember.getClass());
//System.out.println(findMember.getId());
System.out.println(findMember.getUserName());
findMember.getUserName()
호출해서 실제 데이터 조회영속성 컨텍스트
에 초기화 요청 (엔티티 생성 요청)영속성 컨텍스트
가 DB를 조회에서 실제 엔티티 생성프록시 객체
는 생성된 엔티티 객체의 참조를 Member target
멤버변수에 보관프록시 객체
는 실제 엔티티 객체의 getUserName()
을 호출해서 결과를 반환한다.프록시의 특징
프록시 객체를 초기화 할 때 프록시 객체가 실제 엔티티로 바뀌는 것은 아님. 프록시 객체가 초기화 되면 프록시 객체를 통해서 실제 엔티티에 접근 가능
프록시 객체는 원본 엔티티를 상속 받으므로 타입 체크시 주의해야함 ( == 비교 대신에 instance of 사용)
Member findMember1 = em.getReference(Member.class, m.getId());
System.out.println(findMember1.getClass() == Member.class); //false
System.out.println(findMember1 instanceof Member); //true
em.getReference()
를 호출해도 실제 엔티티 반환Member findMember1 = em.find(Member.class, m.getId());
Member findMember2 = em.getReference(Member.class, m.getId());
System.out.println(findMember1.getClass());
System.out.println(findMember2.getClass());
// 출력 => 둘다 엔티티 반환
class com.jpa.db.Member
class com.jpa.db.Member
em.detach(findMember1);
System.out.println(findMember1.getUserName());
//커넥션 에러
org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl stop
PersistenceUnitUtil().isLoaded()
: 프록시 인스턴스의 초기화 여부 확인
Member refMember = em.getReference(Member.class, m.getId());
//System.out.println(refMember.getClass());
System.out.println(emf.getPersistenceUnitUtil().isLoaded(refMember));
초기화 되지 않았을 경우 false 반환. 이미 초기화 되었거나 프록시 인스턴스가 아닐 경우 true 반환