기록과 정리

프록시와 즉시로딩, 지연로딩 본문

IT/JPA

프록시와 즉시로딩, 지연로딩

zepetto 2021. 2. 23. 22:42

이 글은 김영한님의 자바 ORM 표준 JPA 프로그래밍을 참고하였습니다.

www.inflearn.com/course/ORM-JPA-Basic/dashboard

 

자바 ORM 표준 JPA 프로그래밍 - 기본편 - 인프런

JPA를 처음 접하거나, 실무에서 JPA를 사용하지만 기본 이론이 부족하신 분들이 JPA의 기본 이론을 탄탄하게 학습해서 초보자도 실무에서 자신있게 JPA를 사용할 수 있습니다. 초급 웹 개발 프로그

www.inflearn.com

 

프록시 

강의에서는 항상 공부하기 전에 왜 쓰는지 알고 공부하자고 한다.

엔티티에 속해져있는 엔티티의 경우, 전자의 엔티티의 조회할때 항상 조회해져야만 하는가?

 

JPA에서는 조회를 할때 find를 사용하지만 getRefence() 메소드를 이용하여 후자의 엔

티티 조회를 미룰 수 있다.

실제 엔티티 객체를 생성하지 않고 데이터베이스에 접근하기 위한 가짜 프록시 객체를 반환한다.

프록시 객체 조회

해당 코드에서 findMember 를 만들면서 프록시 객체를 생성한다. 해당 코드를 조회해보면 



HibernateProxy 라는 proxy 객체를 확인 할 수 있다. id 값의 경우 가짜 레퍼런스 객체를 가져올떄 사용했으므로 보이지만

이후 쿼리를 날리는 JPA

getUsername을 호출하는 시점에 실제 쿼리를 날리는 것을 확인 할 수 있다.  프록시 객체는 실제 엔티티가 생성되어 있지 않으면 실제 엔티티 생성 요청을 보내는데 이것을 초기화라고 정의한다. 그렇게 실제 엔티티가 생성되고 프록시 객체는 getName을 반환하게 된다.

 

프록시 객체는 실제 엔티티와 바뀌는 것이 아닌 접근 가능하도록 되어지는 것이며 주의 사항으로 객체간 비교시 instance of 를 사용한다.

 

즉시로딩과 지연로딩

프록시 객체는 지연 로딩시에 사용된다.

 

즉시로딩은 엔티티 조회시 연관된 엔티티도 함께 조회한다. 실무에서는 거의 사용하지 않는데 각 연관된 테이블을 무수히 조인해서 가져오기 때문에 성능상 단점이 있다.

 

지연로딩은 연관된 엔티티를 실제 사용시 조회를 한다. ( 예 - @ManyToOne(fetch = FetchType.Lazy )

실제로 사용할 때 쿼리 호출

실제 사용될 때 까지 데이터 로딩을 미루다가 실제 사용시 쿼리를 호출함을 지연로딩이라 한다.

즉시 로딩의 대안으로 fetch join과 엔티티 그래프가 있다. -> 뒤에서 자세히 알아보도록 하자.

 

@ManyToOne , @OneToOne 은 기본전략으로 eager 즉시로딩

@OneToMany , @OneToMany 은 기본전략으로 Lazy 지연로딩

 

+영속성 전이 cascade

특정 엔티티와 관련된 엔티티를 같이 영속상태로 전이를 하고 싶을 때, cascade를 이용한다. 가령 부모와 자식 엔티티

해당 소스를 실행시 parent 객체만 persist하더라도 child1, child2 객체 역시 영속관계가 된다. casecade로 관리할 수 있으며 부모 엔티티의컬렉션에서 자식 엔티티의 참조만 제거하면 자식 엔티티의 엔티티가 자동으로 삭제되는 orpanRemoval = true 옵션값도 존재한다.