본문 바로가기
개발공부 개발새발/DB

JPA) 프록시란 무엇인가

by 휴일이 2022. 11. 25.





프록시?

em.find() 실제 객체 조회
getReference() DB 조회를 미루는 가짜(프록시) 엔티티를 조회함니다
ㄴ 껍데기는 있는데 안에가 비어있음



프록시

실제 객체의 참조를 보관하고
프록시 객체를 호출하면?
실제 객체 메소드를 호출합니다


프록시 객체에서 메소드를 호출하면?
1. 영속성 콘텍스트에 초기화를 요청함
2. DB에서 조회해줌
3. 실제 Entity 생성함
4. 프록시 객체에 target(진짜 엔티티 객체를 가리키는 녀석)으로
해당 메서드를 불러온다
(마치 객체에 주소가 없다가 초기화해서 주소를 넣는 것과 비슷한듯)


**프록시 특징**

- 프록시 객체는 처음 사용할 때 한 번만 초기화됨

- 프록시 객체를 초기화할 때, 프록시 객체가 실제 엔티티로 바뀌는 게 아님
프록시 객체를 통해서 실제 엔티티에 접근이 가능한 것뿐

- 프록시 객체는 원본 엔티티를 상속받을 뿐임, 그래서 타입 체크를 주의하세용
(== 비교 실패(같은 타입이라고 안 뜸), 대신 instance of 사용하기)

- 영속성 컨텍스트에 찾는 엔티티가 이미 있다면,
em.getReference()를 호출해도 실제 엔티티가 호출된다
ㄴ 같은 트랜잭션 안에서는 같은 엔티티라고 보장해주기 때문에 (== true) 그냥 원래 엔티티 반환해줌
ㄴ Reference 먼저 호출하고, 그 다음에 find로 호출해도 find는 proxy를 반환한다

- 영속성 컨텍스트의 도움을 받을 수 없는 준영속 상태라면?
** 프록시를 초기화하면 문제가 발생합니다 ㅠ0ㅠ(찾을 수 없음)


프록시 확인하기

프록시 인스턴스의 초기화 여부 확인
emf.PersistenceUnitUtil().isLoaded(Object entity) 

프록시 클래스 확인 방법
entity.getClass()(..javasist.. or 
HibernateProxy…) 

프록시 강제 초기화
Hibernate.Hibernate.initialize(entity); 
참고: JPA 표준은 강제 초기화 없음
ㄴ member.getName() 이런식으로 강제초기화



실제 클래스를 상속받음, 그래서 껍데기가 같음
사용자는 어차피 걔가 진짜 사용할 때 쿼리가 나가니까
진짜 객체인지 프록시 객체인지 구분 안 하고 사용할 수는 있음(이론상 가능)

728x90