🟩 프록시
다음과 같은 회원 엔티티을 조회할 때 팀에 대한 정보까지 조인해서 가져오게 된다.
@Entity
public class Member {
@Id @GeneratedValue
private Long id;
@ManyToOne
private Team team;
}
@Entity
public class Team {
@Id @GeneratedValue
private Long id;
}
회원에 대한 로직을 수행할 때 팀에 대한 정보가 필요하다면 유용할 수 있다.
하지만 팀에 대한 정보가 필요없다면 비용만 증가할 뿐이다.
사실 이런 문제는 엔티티를 실제 사용하는 시점에서 데이터베이스에서 조회할 수 있도록 하면된다.
이러한 행동을 EntityManager.getReference()를 통해서 조회를 미룰 수 있다.
EntityManager.getReference() 메서드를 호출하면 실제 엔티티 객체가 아닌 프록시 객체를 반환한다.
01. 프록시 객체란?
다른 객체에 대한 대리자 역할을 수행한다.
실제 클래스를 상속 받아서 만들어지는 형태로 사용하는 입장에서는 진짜 객체와 구별하지 않아도 된다.
이러한 프록시 객체는 실제 객체를 참조하고 있다.
만약 사용자가 프록시 객체에게 실제 객체에 대한 정보를 요청했을 때 실제 데이터베이스에서 조회해서 실제 엔티티를 생성하게 된다.
02. 프록시 특징
- 프록시 객체는 처음 사용할 때 한 번만 초기화 된다.
- 프록시 객체는 초기화 했다고해서 실제 엔티티로 바뀌지는 않는다.
(프록시 객체를 통해서 실제 엔티티에 접근할 수 있게 된다.) - 원본 엔티티를 상속받은 객체이므로 타입 체크에 주의해야 한다.
- 영속성 컨텍스트에 찾는 엔티티가 있다면 데이터베이스를 조회하지 않는다.
- 프록시 객체를 초기화하기 위해서는 영속성 컨텍스트의 도움을 받아야 한다.
- 영속성 컨텍스트의 도움을 받지 못하는 상황에서 프록시 객체를 초기화 시도하면 LazyInitializationException 예외가 발생한다.
🟩 즉시 로딩, 지연 로딩
01. 즉시 로딩 (Eager Loading)
- 엔티티를 조회할 때 연관된 엔티티도 함께 조회한다.
회원, 팀 매핑 코드
@Entity
public class Member {
@Id @GeneratedValue
private Long id;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "team_id")
private Team team;
}
@Entity
public class Team {
@Id @GeneratedValue
private Long id;
private String name;
}
회원을 조회하면 팀 엔티티를 조인해서 같이 조회한다.
Member member = em.find(Member.class, "1L");
select
m1_0.id,
t1_0.id,
t1_0.name
from
member m1_0
left join
team t1_0
on t1_0.id=m1_0.team_id
where
m1_0.id=?
02. 지연 로딩 (Eager Loading)
- 즉시 로딩에서 회원을 조회했을 때 팀 엔티티까지 조회하게 됐다.
하지만 팀이 지연 로딩되게 설정하면 회원만 조회해오게 된다.
@Entity
public class Member {
@Id @GeneratedValue
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "team_id")
private Team team;
}
@Entity
public class Team {
@Id @GeneratedValue
private Long id;
private String name;
}
팀이 지연 로딩 되도록 설정해줬기 때문에 회원만 조회하게 된다.
그리고 Member.team에는 프록시 객체가 들어가게 된다.
Member member = em.find(Member.class, "1L");
select
m1_0.id,
m1_0.team_id
from
member m1_0
where
m1_0.id=?
이후에 회원 엔티티에서 팀 엔티티를 접근하려고 할 때 데이터베이스에서 팀을 조회하게 된다.
String teamName = member.getTeam().getName();
select
t1_0.id,
t1_0.name
from
team t1_0
where
t1_0.id=?
🔗 참고
자바 ORM 표준 JPA 프로그래밍 - YES24
자바 ORM 표준 JPA는 SQL 작성 없이 객체를 데이터베이스에 직접 저장할 수 있게 도와주고, 객체와 관계형 데이터베이스의 차이도 중간에서 해결해준다. 이 책은 JPA 기초 이론과 핵심 원리, 그리고
www.yes24.com