8장. 프록시
- 📚 Spring/Spring JPA
- 2023. 8. 28. 17:17
⚡ 프록시
- 객체는 객체그래프로 연관된 객체들을 탐색한다. 그런데 객체가 데이터베이스에 저장되어 있으므로 연관된 객체를 마음껏 탐색하기는 어렵다.
- JPA는 이러한 문제를 해결하려고 프록시라는 기술을 사용한다.
- 프록시는 연관된 객체를 처음부터 데이터베이스에서 조회하는 것이 아니라, 실제 사용하는 시점에 데이터베이스에서 조회할 수 있다. 하지만 자주 함께 사용하는 객체들은 조인을 사용해서 함께 조회하는 것이 효과적이다.
- JPA는 즉시로딩과 지연 로딩이라는 방법으로 둘을 지원한다.
- JPA는 연관된 객체를 함께 저장하거나 함께 삭제할 수 있는 영속성 전이와 고아 객체 제거라는 편리한 기능을 제공한다.
⚡ 프록시의 특징
- 프록시 객체는 처음 사용할 때 한 번만 초기화 된다.
- 프록시 객체를 초기화 할 때, 프록시 객체가 실제 엔티티로 바뀌는 것은 아님, 초기화되면 프록시 객체를 통해서 실제 엔티티에 접근 가능
- 프록시 객체는 원본 엔티티를 상속받음, 따라서 타입 체크시 주의해야함 (== 비교 실패, 대신 instance of 사용)
- 영속성 컨텍스트에 찾는 엔티티가 이미 있으면 em.getReference()를 호출해도 실제 엔티티 반환
- 영속성 컨텍스트의 도움을 받을 수 없는 준영속 상태일 때, 프록시를 초기화하면 문제 발생
(하이버네이트는 org.hibernate.LazyInitializationException 예외를 터트림)
📝 프록시 예제
public class JpaMain {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
try {
Member member = new Member();
member.setUsername("kuser");
em.persist(member);
Member member2 = new Member();
member2.setUsername("aa");
em.persist(member2);
em.flush();
em.clear();
Member findMember = em.find(Member.class, member.getId());
Member refMember = em.getReference(Member.class, member2.getId());
System.out.println("findMember = " + findMember.getClass());
System.out.println("refMember = " + refMember.getClass());
System.out.println("(findMember == refMember) = " + (findMember == refMember));
System.out.println("(findMember instanceof Member) = " + (findMember instanceof Member));
System.out.println("(refMember instanceof Member) = " + (refMember instanceof Member));
tx.commit();
} catch (Exception e) {
tx.rollback();
} finally {
em.close();
}
emf.close();
}
}
📝 결과
findMember = class hellojpa.Member
refMember = class hellojpa.Member$HibernateProxy$PPn3ifLH
(findMember == refMember) = false
(findMember instanceof Member) = true
(refMember instanceof Member) = true
'📚 Spring > Spring JPA' 카테고리의 다른 글
8장. 프록시 - 지연로딩 (0) | 2023.08.30 |
---|---|
다대일 단반향 - 다대일 양방향 (0) | 2023.08.27 |
[Spring JPA #7] 7장. 고급매핑 (0) | 2023.08.26 |
[정리] 준영속 (0) | 2022.03.17 |
[정리] 플러시 (flush()) (0) | 2022.03.16 |