경로 표현식이란?
.(점)을 찍허 객체 그래프를 탐색하는 것이다.
다음과 같은 코드가 있다고 가정해보자.
@Entity
public class Member {
@Id @GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "TEAM_ID")
private Team team;
@OneToMany(mappedBy = "member")
private List<Order> orders = new ArrayList<>();
private String username;
}
단순히 Team은 @ManyToOne으로 다대일 연관관계를 맺어주고, Order는 @OneToMany로 일대다 연관관계를 맺어주었다. 이 필드들을 경로 표현식으로 탐색하자면 다음과 같다.
- 상태 필드: 단순히 값을 저장하기 위한 필드
- 연관 필드: 연관관계를 위한 필드
- 단일 값 연관필드(@ManyToOne, @OneToOne): 대상이 엔티티
- 컬렉션 값 연관 필드(@OneToMany, @ManyToMany): 대상이 컬렉션
경로 표현식 특징
상태필드: 경로 탐색의 끝이다. 더이상 탐색을 안한다.
단일 값 연관 필드: 묵시적 내부 조인 발생, 더 탐색을 할 수 있다.
String query = "select m.team from Member m";
List<Team> resultList = em.createQuery(query, Team.class).getResultList();
for (Team team : resultList) {
System.out.println("team.getName() = " + team.getName());
}
query에 m.team으로 단일 값 연관 필드를 조회해보자.
Hibernate:
select
t1_0.id,
t1_0.name
from
member m1_0
join
team t1_0
on t1_0.id=m1_0.team_id
team.getName() = teamA
JPQL에서는 Member을 조회하는 쿼리를 작성했지만 실행결과에서의 from절에 Team을 JOIN해서 조회하는것을 볼 수 있다.
이걸 묵시적 내부조인이라고 한다. 이러한 기능은 매우 편리해보이지만 매우 조심해야한다.
쿼리가 한두개가 아닌 몇십개가 나가야할 때는 버그가 발생할 수도 있고 튜닝하기도 매우 어렵기 때문이다.
컬렉션 값 연관 경로: 묵시적 내부 조인 발생한다. 더이상 탐색은 안된다.
@Entity
public class Team {
@Id @GeneratedValue
private Long id;
@OneToMany(mappedBy = "team")
private List<Member> members = new ArrayList<>();
private String name;
@Override
public String toString() {
return "Team [id=" + id + ", name=" + name + "]";
}
}
일대 다 관계는 컬렉션의 안에있는 값들이 몇개들어있는지도 모르고, 어느 필드를 꺼내야할지 난감하다. JPA에서는 컬렉션 값 연관필드는 묵시적 내부조인은 발생하지만 탐색은 못하는 제약을 뒀다.
그러면 탐색이 아예 불가능하다?는 아니다.
String query = "select m.username from Team t join t.members m";
em.createQuery(query, Member.class).getResultList();
FROM절의 명시적 조인을 활용하면 탐색이 가능하게 된다.
'JPA' 카테고리의 다른 글
[JPA] 페치조인과 일반 조인의 차이점 (1) | 2024.12.27 |
---|---|
[JPA] JPQL의 프로젝션, 페이징 (0) | 2024.12.24 |
[JPA] JPA의 타입 (임베디드 타입, 값 타입, 컬렉션 타입)이란? (1) | 2024.12.20 |
[JPA] 프록시와 지연로딩, 즉시로딩 (0) | 2024.11.26 |
[JPA] 연관관계 매핑 (0) | 2024.11.25 |