728x90
📌 프록시
1) 배경
엔티티를 조회할 때 연관된 엔티티가 존재하는 경우 두 가지 방법으로 조회 방법이 나뉜다. 연관된 엔티티를 데이터베이스에서 즉시 조회하는 경우와 프록시로 조회하는 경우다. 이에 따라 즉시 로딩, 지연 로딩으로 나뉘는 데 이 중 프록시를 활용한 전략법은 지연 로딩(LAZY)에 해당한다.
프록시를 사용하면 연관된 객체를 처음부터 데이터베이스에서 조회하는 것이 아닌, 실제 사용하는 시점에 데이터베이스에서 조회할 수 있다.
그렇다면 프록시란 무엇일까?
2) 정의
프록시 객체
: 실제 엔티티 객체 대신에 데이터베이스 조회를 지연할 수 있는 가짜 객체
프록시 클래스는 실제 클래스를 상속 받아서 만들어지므로 실제 클래스와 겉 모양이 같다. 따라서 가짜 객체인지 진짜 객체인지 구분하지 않고 사용하면 된다.
3) 특징
- 처음 사용할 때 한 번만 초기화 된다.
- 프록시 객체를 통해서 실제 엔티티에 접근할 수 있고, 실제 엔티티의 메서드 역시 호출한다.
- 영속성 컨텍스트에 찾는 엔티티가 이미 있으면, 데이터베이스를 조회할 필요가 없다. 따라서 em.getReference()로 실제 엔티티를 호출한다.
- 초기화는 영속성 컨텍스트의 도움을 받아야 하기에, 준영속 상태에서 프록시를 초기화하게 되면 예외를 발생시킨다. (org.hibernate.LazyInitalizationException)
4) 확인법
해당 객체가 프록시인지 확인 하는 방법은 다음과 같다.
- PersistenceUnitUtil.isLoaded(Object entity) : 프록시 인스턴스 초기화 여부 확인(true/false)
- entity.getClass().getName() : 프록시 클래스 이름 확인
📌 즉시 로딩과 지연 로딩
1) 즉시 로딩
fetch 속성을 FetchType.EAGER 로 지정
@Entity
public class Member {
// ...
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "TEAM_ID")
private Team team;
// ...
}
멤버와 팀 두 테이블을 조회할 때 데이터베이스에서 직접 조회한다. 쿼리가 2번 나갈 것 같지만, 조인(JOIN)을 통해 두 엔티티를 동시에 조회한다.
일반적으로 LEFT OUTER JOIN 이란 외부조인이 사용되는 데, 그 이유는 현재 멤버테이블에서 TEAM_ID는 NULL 값을 허용하고 있기 때문이다. NULL 값이 존재하기에 외부조인으로 자동적으로 쿼리가 나가지만, 성능과 최적화를 위해서는 내부조인(INNER JOIN)이 더 적합하다.
내부조인으로 쿼리를 호출하기 위한 코드는 아래와 같다.
내부 조인 사용 방법
@Entity
public class Member {
// ...
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "TEAM_ID", nullable = false) // 내부 조인 사용
private Team team;
// ...
}
- @JoinColumn(nullable = false)
- @ManyToOne(optional = false)
2) 지연 로딩
fetch 속성을 FetchType.LAZY 로 지정
@Entity
public class Member {
// ...
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "TEAM_ID")
private Team team;
// ...
}
em.find(Member.class, "member1") 와 같이 멤버를 호출하면 멤버만 조회하고 팀은 조회하지 않는다. 대신에 조회한 멤버의 team 변수에 프록시 객체를 넣어둔다. 이 팀 객체는 프록시 객체로, 실제 사용될 때까지 데이터 로딩을 미룬다.
3) 각 로딩 전략 비교
즉시 로딩(EAGER) | 지연 로딩(LAZY) |
연관된 엔티티를 즉시 조회 | 연관된 엔티티를 프록시로 조회 |
@ManyToOne, @OneToOne 과 같이 ~ToOne에 해당하는 기본값 | @OneToMany, @ManyToMany 의 기본값 |
실무에서 비추천 모든 관계를 LAZY로 설정 후 최적화 단계에서 필요 부분만 EAGER로 수정하는 것을 권장 |
실무에서 추천 일반적으로 LAZY 로 설정하는 것을 권장 |
<참고자료>
https://product.kyobobook.co.kr/detail/S000000935744
자바 ORM 표준 JPA 프로그래밍 | 김영한 - 교보문고
자바 ORM 표준 JPA 프로그래밍 | 자바 ORM 표준 JPA는 SQL 작성 없이 객체를 데이터베이스에 직접 저장할 수 있게 도와주고, 객체와 관계형 데이터베이스의 차이도 중간에서 해결해준다. 이 책은 JPA
product.kyobobook.co.kr
728x90
'LANGUAGE > Java' 카테고리의 다른 글
[JPA] @MappedSuperclass (0) | 2024.01.01 |
---|---|
[JPA] 상속관계 매핑 정리- 3가지 전략 JOINED, SINGLE_TABLE 등 (0) | 2023.12.31 |
[JPA] 기본적인 매핑 어노테이션 (4) | 2023.12.17 |