연관관계를 가지는 객체를 조회할때, 연관관계는 가지지만 사용하지 않는 연관관계 객체를 함께 조회한다는 것은 효율적이지 못하다.
그렇기 때문에 사용하는것이 지연로딩으로 연관관계 객체를 사용하는 순간 해당 객체 조회 쿼리를 데이터베이스에 요청한다.(영속성 컨텍스트에 없다고 가정하면)
그렇다면 어떤 객체를 조회했을 때, 지연로딩으로 설정한 연관관계 객체는 객체가 아니라 무엇인가?
Member member = em.find(Member.class, 1);
Team team = member.getTeam(); //??
String name = team.getName(); //실제 객체 조회 SELECT 쿼리 요청
지연로딩으로 설정한 연관관계 객체는 가짜 엔티티
로써 프록시
객체라고 하는 것이다.
프록시
란 실제 객체 상속받는 클래스로 써 실제 객체 처럼 보이는 껍데기(가짜) 객체이다.
프록시 객체는 실제 객체 참조(target)을 가지고 있는데, target을 가지고 실제 객체처럼 사용할 수 있다.
target은 프록시 객체가 처음 만들어 졌을 때는 비어있고 JPA에 의해 초기화 요청을 받았을 때 데이터베이스에서 실제 객체를 가져와 target이 실제 객체를 참조한다.
메서드
JPA를 이용한 hibernate proxy는 아래와 같이 실행된다.
Member member = em.getReference(Member.class, 1); //프록시 객체
String name = member.getName(); //실제 객체 요청
em.getReference(Member.class, 1)
는 실제 id=1인 member 반환.public class Member{
@Id
Long id
@ManyToOne(fetch = FetchType.EAGER)
Team team;
}
엔티티를 조회할때 연관관계 엔티티는 JOIN을 통해 함께 조회된다.
@ManyToOne
, @OneToOne
인 곳. 즉, 연관관계가 하나인 곳에서 즉시로딩이 default
하지만 연관관계 조회 효율성을 위해 지연로딩으로 설정하는 것을 추천하고 효율에 따라서 설정한다.
public class Team{
@Id
Long id
@OneToMany(fetch = FetchType.LAZY)
List<Member> members = new ArrayList<>();
}
엔티티를 조회할때 해당 엔티티만 조회되고 연관관계 엔티티를 사용하는 순간 조회된다.
@OneToMany
, @ManyToMany
인 곳. 즉, 컬렉션인 연관관계인 곳에서 지연로딩이 default
https://ict-nroo.tistory.com/131
https://ultrakain.gitbooks.io/jpa/content/chapter8/chapter8.1.html
https://ultrakain.gitbooks.io/jpa/content/chapter8/chapter8.2.html