본 게시글은 김영한 님의 자바 ORM 표준 JPA 프로그래밍 - 기본편 을 정리한 내용입니다.
필요한 연관관계만 조회해 오는 것이 효과적이다
- JPA를 사용하면 객체 그래프를 통해 연관관계를 탐색할 수 있다
- 엔티티들은 데이터베이스에 저장되어 있다
- 한 객체 조회 시 연관되어 있는 엔티티들을 모두 조회하는 것 보다는 필요한 연관관계만 조회해 오는 것이 좋다
- 이를 위해 JPA는 지연로딩 방식을 지원, 하이버네이트(Hibernate)는 프록시 객체를 통해 지연 로딩을 구현한다
다음과 같은 객체 관계를 가질 때, Member를 조회할 시 Team도 함께 조회해야할까?
단순히 회원 이름만 출력한다면 Team까지 조회 쿼리를 날릴 필요가 없다. 이를 위해 지연로딩을 사용한다.
JPA에서의 프록시
em.find() 와 em.getReference()
- em.find() : 데이터베이스를 통해서 실제 엔티티 객체 조회
- em.getReference(): 데이터베이스 조회를 미루는 가짜(프록시) 엔티티 객체 조회
- 프록시 객체는 실제 클래스를 상속받아 만들어짐
- 최초 지연 로딩 시점에는 Entity target = null
- 실제 객체의 메서드를 호출할 필요가 있을 때 데이터베이스를 조회해서 참조 값을 채우게 되는데, 이를 프록시 객체를 초기화한다고 함
Member member = em.getReference(Member.class, “id1”);
member.getName();
프록시의 특징
- 프록시 객체는 처음 사용할 때 한 번만 초기화
- 프록시 객체를 초기화 할 때, 프록시 객체가 실제 엔티티로 바뀌는 것은 아님, 초 기화되면 프록시 객체를 통해서 실제 엔티티에 접근 가능
- 프록시 객체는 원본 엔티티를 상속받음, 따라서 타입 체크시 주의해야함 (== 비 교 실패, 대신 instance of 사용)
- 영속성 컨텍스트에 찾는 엔티티가 이미 있으면 em.getReference()를 호출해 도 실제 엔티티 반환
- 영속성 컨텍스트의 도움을 받을 수 없는 준영속 상태일 때, 프록시를 초기화하면 문제 발생 (하이버네이트는 org.hibernate.LazyInitializationException 예외를 터트림)
지연 로딩 LAZY
@Entity
public class Member {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "USERNAME")
private String name;
@ManyToOne(fetch = FetchType.LAZY) //**
@JoinColumn(name = "TEAM_ID")
private Team team;
...
}
위와 같을 때
Member member = em.find(Member.class, 1L);
Member 조회시 Team 은 조회 쿼리가 생기지 않는다
Team team = member.getTeam();
team.getName(); // 실제 team을 사용하는 시점에 초기화(DB 조회)
team.getName(); 과 같이 실제 Team을 조회해야 할 때 쿼리가 발생한다.
즉시로딩은 실무에서 사용하지 않는다
Member와 Team을 자주 함께 사용한다면 즉시로딩을 고려해볼 수 있다. 그러나 즉시로딩은 N+1문제 등 예상하지 못한 SQL이 발생하므로 실무에서 사용하지 않는다.
- @ManyToOne, @OneToOne은 기본이 즉시 로딩 -> LAZY로 설정
- @OneToMany, @ManyToMany는 기본이 지연 로딩
- 즉시로딩 대신 JPQL fetch 조인이나 엔티티 그래프 기능을 사용
Reference.
- https://tecoble.techcourse.co.kr/post/2022-10-17-jpa-hibernate-proxy/
'JPA' 카테고리의 다른 글
[JPA] 상속관계 매핑, @MappedSuperclass (0) | 2022.07.28 |
---|---|
[JPA] 다대일,일대다,일대일,다대다 (@ManyToOne,@OneToMany,@OneToOne,@ManyToMany) (0) | 2022.07.28 |
[JPA] JPA 설정하기 (0) | 2022.07.28 |
[JPA] 연관관계 매핑 기초 (0) | 2022.07.28 |
[JPA] 엔티티 매핑 (0) | 2022.07.28 |
댓글