JPA에서의 프록시는 어떻게 사용하는지 정리해보겠습니다.
간단한 이해를 돕기 위해 이전에 작성했던 포스팅 정보를 첨부해놓겠습니다.
https://applepick.tistory.com/159
프록시 특징
실제 클래스를 상속받아서 만들어집니다. 사용하는 입장에서 진짜 객체인지 프록시 객체인지 구분하지 않고 사용하면 됩니다.(때에 따라서...) 프록시 객체는 실제 객체의 참조(Target)를 보관합니다.
프록시 객체는 처음 사용할 때 한 번만 초기화
프록시 객체는 원본 엔티티를 상속받습니다. 따라서 타입 체크할 때 중요합니다. ( ==으로 비교 시 프록시 객체와 실제 객체를 비교하여 실패할 수 있습니다. instance of 로 사용)
프록시 객체를 호출 -> 프록시 객체는 실제 객체의 메소드를 호출 순으로 이어집니다.
프록시 객체의 초기화 순서 (하이버네이트 기준)
유저가 getName()을 요청 -> 프록시 객체의 맴버 타겟이 없으면 JPA가 영속성 컨텍스트에게 요청 -> 영속성 컨텍스트가 DB에서 조회 -> 조회된 값으로 실제 Entity 생성 -> 프록시 객체의 target에 진짜 객체를 연결 -> 동일한 객체 조회 시 DB를 다시 거쳐오는 것이 아닌 프록시객체에 있는 값을 반환
주의
위 상황에서 초기화를 영속성 컨텍스트에게 요청을 하였는데 영속성 컨텍스트가 꺼지는 상황이 생기고 다시 조회 요청을 보내면 어떻게될까?
영속성 컨택스트의 도움을 받을 수 없는 준영속 상태일 때, 프록시를 초기화하면 문제가 발생합니다. 그 이유는 영속성 컨텍스트가 관리하던 것이 날라가게되어 LazyInitializationException 발생합니다.
프록시 객체를 초기화 할 때 프록시 객체가 실제 엔티티로 바뀌는 것이 아닙니다. 초기화가 되면 프록시 객체를 통해서 실제 엔티티에 접근가능합니다.
영속성 컨텍스트에 찾는 엔티티가 이미 있으면 getReference()를 호출해도 실제 엔티티를 반환합니다. 그 이유는 JPA는 같은 영속성컨텍스트 트랜잭션 안에서 발생한 객체의 반환 값을 항상 동일해아합니다. (그 반대 상황도 마찬가지)
'혼자 공부하는 것들 > JPA' 카테고리의 다른 글
주문조회 페이징 처리 API 설계하면서 고민했던 점 및 트러블 슈팅 (1) | 2022.09.24 |
---|---|
[Spring + JPA] 동시성 문제를 해결해보자! (0) | 2022.09.09 |
[지구최강 JPA 스터디] 6-7주차 연관관계 매핑 4가지와 단방향, 양방향! (0) | 2022.08.14 |
[지구최강 JPA 스터디] 4-5주차 객체 설계 할때는 단방향으로!? (0) | 2022.07.28 |
[지구최강 JPA 스터디] 2-3주차 몰아서 정리하자! (1) | 2022.07.13 |
댓글