Search
Duplicate
📒

[JPA 기본] 08-1. 프록시

상태
완료
수업
JPA
주제
JPA
4 more properties
참고

프록시

NOTE
엔티티를 조회할 때, 연관된 엔티티들이 항상 사용되는 것은 아니다. 연관관계의 엔티티는 비즈니스 로직에 따라 사용될 때도 있지만, 그렇지 않을 때도 있다.
// CASE 1. Member, Team 객체 조회 필요 public void printUserAndTeam(String memberId) { Member member = em.find(Member.class, memberId); Team team = member.getTeam(); System.out.println("회원 이름: " + member.getUsername()); System.out.println("소식팀: " + team.getName()); // team 객체 조회 } // CASE 2. Member 객체 조회 필요 public void printUser(String memberId) { Member member = em.find(Member.class, memberId); Team team = member.getTeam(); System.out.println("회원 이름: " + member.getUsername()); }
Java
복사
JPA는 이런 문제를 해결하려고 엔티티가 실제 사용될 떄까지 데이터베이스 조회를 지연하는 방법을 제공하는데 이것을 지연 로딩이라고 한다.
그런데 지연 로딩을 사용하기 위해서는 실제 엔티티 객체 대상에 데이터베이스 조회를 지연할 수 있는 가짜 객체가 필요한데 이것을 프록시 객체라 한다.

사용 함수

em.find
데이터베이스를 통해서 실제 엔티티 객체 조회
em.getReference()
데이터 베이스 조회를 미루는 가짜(프록시) 엔티티 객체 조회
entityManagerFactory.getPersistenceUnitUtil().isLoaded(object)
프록시 인스턴스의 초기화 여부 확인
entity.getClass().getname()
프록시 클래스 확인 방법

프록시 특징

NOTE
프록시 객체는 처음 사용할 때 한 번만 초기화 된다.
프록시 객체는 원본 엔티티를 상속받은 객체이므로, 타입 체크 시에 주의해서 사용해야 한다.
하이버네이트에서는 프록시와, 원본 엔티티가 항상 ==True임을 보장해야 한다.
영속성 컨텍스트에 이미 엔티티가 있다면, 데이터베이스에서 조회하지않고, em.getReference()를 호출해도 실제 엔티티를 반환한다.
Member m1 = em.find(Member.class, member1.getId()); System.out.println("m1 = "+ m1.getClass()); //Member Member reference = em.getReference(Member.class, member1.getId()); System.out.println("reference = " reference.getClass()); //Member m1 == reference //true
Java
복사
초기화는 영속성 컨텍스트의 도움을 받아야만 가능하다. 따라서 영속성 컨텍스트의 도움을 받을수 없는 준영속 상태, 프록시 초기화에서는 문제가 발생한다.
LazyInitializationException예외가 발생한다.

프록시 초기화

NOTE
프록시 초기화
Member member = em.getRefernce(Member.class, "id1");//(1) member.getName();//(2)-
Java
복사
1.
코드 라인에서 getReference()를 호출하면 프록시 객체를 가져오고, getName()을 호출하면 JPA가 영속성 컨텍스트에 초기화를 요청한다.
2.
영속성 컨텍스트에서는 실제 DB를 조회해서 가져온 다음 실제 Entity에 값을 넣어 생성하고, 프록시 객체는 실제 엔티티를 연결해서 실제 엔티티를 반환한다.
3.
그 이후에는 이미 초기화 되어있는 프록시객체 이기에 해당 엔티티를 반환한다.