프록시 V2

Shaun·2021년 10월 27일
0

JPA

목록 보기
19/31

기존 프록시 학습에대해 내용을 추가 하였다

프록시

  • em.find() 는 실제 객체를 불러오고 em.getReference() 는 프록시(가짜객체)를 불러온다
  • 맵핑이 잘돼잇는 상태에서 find()를 사용하면 jpa는 연관된 객체까지 다 select 해온다. (JPA 가 알아서 JOIN 을 해서 가져온다)

  • reference 만 사용했을때는 가짜객체(프록시)를 가져온다 . 하지만 그 객체의 정보를 사용하는 순간(필드를 불러오는) db에 쿼리문을 날려 연관된 값을 다 가져온다.(진짜객체)

프록시 특징

  • 프록시는 실제 클래스를 상속 받아서 만들어 진다

  • 실제 클래스와 겉 모양이 같다

  • 프록시 객체는 실제 객체의 참조(target)를 보관한다.

  • 프록시 객체를 호출하면 프록시 객체는 실제 객체의 메소드 호출

프록시 진행방향(프록시 객체 초기화)

  • Member -> Team 있다고 가정해보면 Team 클래스를 부를 떄까지는 프록시(가짜객체)가 나온다

  • 하지만 team의 데이터를 직접건드리는 순간 진짜 데이터객체가 target에 진짜 객체를 연결해준다

  • target 은 처음에는 null이다(프록시)

주의!

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

• 프록시 객체를 초기화 할 때, 프록시 객체가 실제 엔티티로 바뀌는 것은 아님, 초
기화되면 프록시 객체를 통해서 실제 엔티티에 접근 가능

• 프록시 객체는 원본 엔티티를 상속받음, 따라서 타입 체크시 주의해야함 (== 비
교 실패, 대신 instance of 사용)

• 영속성 컨텍스트에 찾는 엔티티가 이미 있으면(find()) em.getReference()를 호출해
실제 엔티티 반환( 진짜 데이터 영속성 컨텍스트에 넣어놨는데 굳이 프록시 가져올필요 없다)

-> 그 반대로 먼저 getReference(프록시) 가 호출되고 find()를 호출하면 find()에서는 프록시가 호출 된다(a==a 법칙때문)

JPA에서는 A == A의 결과는 True이다

  • find() 결과==getReference() 결과 (한영속성에서 가져오고 pk값 같으면) 항상 true
  • 프록시로 가져오면 ==할떄 타입안맞아 false나옴 (무조건 true여야됌) ->
    그래서 프록시로 반환해봐야 이점도 없고 a==a true로 만들어주기위해 진짜객체를 가져온다

- 영속성 컨텍스트의 도움을 받을 수 없는 준영속 상태일 때, 프록시를 초기화하면
문제 발생 (= 영속성 컨텍스트를 날려버리면 DB에서 데이터를 가져올수 없기 때문)
(하이버네이트는 org.hibernate.LazyInitializationException 예외를 터트림)

profile
호주쉐프에서 개발자까지..

0개의 댓글