본문 바로가기

JPA

JPA 프록시란?

오늘은 JPA 프록시에 대해 정리해보겠습니다.

모든 설명과 강의 자료는 김영한 강사님 JPA 강의를 참고했습니다.

 

Member를 조회할 때, Team도 함께 조회해야 할까?

예를 들어, 멤버의 유저 네임만 출력하는 비지니스 로직이 있다고 가정해봅니다. 이때, DB에서 멤버와 팀이 연관 관계를 맺고 있다고 하여 팀 테이블까지 쿼리문을 사용하여 조회하거나 등의 동작을 수행하면 손해입니다. 
즉, 사용하지 않는 테이블을 조회하거나 가져오는 등의 접근은 최적화가 되지 않은 것입니다.

JPA는 이런 문제를 지연 로딩이랑 프록시로 해결합니다.
이번 시간에는 프록시에 대해서 알아보겠습니다.

 


프록시란 무엇인가?

프록시는 JPA에서 실제 엔티티 객체 대신 데이터베이스 조회를 지연할 수 있는 가짜 객체를 의미합니다.

프록시는 실제 엔티티 클래스를 상속받아 만들어지므로 사용자 입장에서는 실제 엔티티 클래스와 겉모양이 동일하므로 가짜 객체인지 진짜 객체인지 구분하지 않고 사용하면 됩니다.


프록시의 동작 과정 

JPA에서는 EntittyManager가 em.find() 메소드 말고 em.getReference() 메소드를 제공합니다.

em.getReference()는 데이터베이스에서 조회를 미루는 프록시 엔티티 객체를 조회하는 것입니다.

이것은 DB에 쿼리문이 실행되지 않았는데 객체가 조회되는 것을 의미합니다.

 

이게 어떻게 가능한 일일까요?

 

 

 

1.사용자가 getName()을 호출

2.Member taget의 값이 처음에는 없으므로,  JPA가 영속성 컨택스트에 조회하려는 객체의 초기화 요청.
초기화 요청 : DB를 통해서 값을 가지고 와서 진짜 엔티티를 만들어내는 과정.

3.영속성 컨택스트는 DB에 조회해서 실제 엔티티 객체를 생성함.

4.그리고 영속성 컨택스트는 프록시의 target과 실체 객체를 연결해줌

5.결과적으로 사용자가 getName()을 호출하면 target(실제 객쳬)로 접근하여 getName()을 통해 실제 객체의 멤버에 있는
getName()을 호출한다.

6. 처음에 target에 값이 없기 때문에 DB에 접근하여 쿼리문을 호출해야 하지만, 한번 초기화한 다음에는 target에 실제 객체가 연결되어 있기 때문에 DB의 쿼리문을 수행하지 않아도 된다.

 

 

 


 

프록시의 특징 

프록시 객체는 처음 사용할 때 한번만 초기화 됩니다.

또한, 가장 주의해야 할 부분은 프록시 객체를 초기화 할 때, 프록시 객체가 실제 엔티티로 바뀌는 것은 아닙니다. 초기화가 되면 프록시 개체를 통해서 실제 엔티티에 접근이 가능할 뿐입니다.

 

 

참고:

https://www.inflearn.com/course/ORM-JPA-Basic