프록시

김민지·2022년 10월 19일
0

JPA

목록 보기
8/27

개념

  • JPA에서 프록시는 연관된 객체들을 데이터베이스에서 조회하기 위해서 사용합니다.
    프록시를 사용하면 연관된 객체들을 처음부터 데이터베이스에서 조회하는 것이 아니라 실제 사용하는 시점에 데이터베이스에서 조회할 수 있습니다.
  • 하지만 자주 함께 사용되는 객체들은 조인을 사용해서 함께 조회하는 것이 더 효과적입니다. JPA는 즉시로딩과 지연로딩이라는 방법으로 둘을 모두 지원하고 있습니다.

준영속상태

  • 준영속상태의 객체를 참조하려고하면 오류가난다
  • 엔티티를 실제 사용하는 시점까지 데이터베이스 조회를 미루고 싶을때 사용하는게 프록시다.
    데이터베이스에서 조회를해왔어도 초기화 되지 않은(참조를할 수 없는) 프록시객체이기 때문에
    실제 사용하는 시점에서 영속상태이지 않으면 참조를 할 수 없다
  • 영속상태여야 아래의 과정을 거칠 수 있다
  1. 프록시 객체는 실제 엔티티가 생성되어 있지 않으면 영속성 컨텍스트에서 실제 엔티티 생성을 요청하는데 이것을 초기화라고 합니다.
  2. 영속성 컨텍스트는 데이터베이스를 조회해서 실제 엔티티 객체를 생성합니다.
  3. 프록시 객체는 생성된 실제 엔티티 객체의 참조를 Member target 맴버 변수에 보관합니다.
  4. 프록시 객체는 실제 엔티티 객체의 getName()을 호출해서 결과를 반환합니다.
    그런데 준영속상태라면 관리를 받지 않는 상태이니 위의 과정을 못거치게 되고, 오류가 나게된다

id로 프록시 초기화 시도

Team team = em.getReference(Team.class, 1l); //식별자 보관
team.getId();
  • 프록시객체를 얻어올때 보통 id값으로 조회해온다. 그리고 프록시객체는 이 id값을 기억한다.
    그렇기 때문에 프록시객체에 대해 id값을 참조해도 초기화가 되지 않는다.

영속성컨텍스트에 존재한다면?

  • 만약에 조회하려는 객체가 영속성 컨텍스트에 이미 존재한다면 프록시 객체가 아니라 엔티티객체를 가져오게 된다

정리

.getReference()로 가져오면 일단 프록시객체를 준다
내가 .getName처럼 id를 제외한 필드에 접근을 해야만 진짜 객체를 초기화해서 준다
근데 이 과정에서 준영속이 되어버린다면 접근을 할 수 없게된다.
1. 만약에 초기화하는 과정에서 영속성컨텍스트에 있었다면 어떻게 됐을까?

  • 애초에 영속성컨텍스트에 있었다면 .getReference을 했을때 영속성컨텍스트에서 가져왔을것이다.
    그래서 프록시 객체가 아닌 엔티티 객체였을것이다

출처
https://velog.io/@sa1341/JPA-Proxy

profile
안녕하세요!

0개의 댓글