Notice
Recent Posts
Recent Comments
Link
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | |||
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| 12 | 13 | 14 | 15 | 16 | 17 | 18 |
| 19 | 20 | 21 | 22 | 23 | 24 | 25 |
| 26 | 27 | 28 | 29 | 30 |
Tags
- design-pattern
- 클린 아키텍처
- DevOps
- SpringBoot
- 헥사고날 아키텍처
- 글또10기
- 다짐글
- Level2
- 클라우드아키텍처
- 레벨1
- UserLand
- axios
- 코엑스그랜드볼룸
- 코딩테스트
- object-creation
- ReverseNested
- builder-pattern
- 글쓰기세미나
- static-factory-method
- 회고
- 포트앤어댑터 아키텍처
- constructor
- React
- QueryDSL
- 글또
- HashMap
- 3계층 아키텍처
- 프로그래머스
- OpenSearch
- 가용영역
Archives
- Today
- Total
oguri's garage
JPA에서 DISTINCT가 필요한 경우와 필요하지 않은 경우 본문
상황
프로젝트에서 JOIN FETCH 쿼리를 작성했는데, 어떤 코드는 DISTINCT가 필요하고 어떤 코드는 필요하지 않다고 해서 해당 상황을 정리해보았다.
내가 작성한 코드:
@Query("SELECT om FROM OrderMember om " +
"JOIN FETCH om.member " +
"WHERE om.orderId = :orderId")
List<OrderMember> findByOrderIdWithMember(
@Param("orderId") Long orderId
);
핵심: 조회 방향이 중요하다
1. ManyToOne 조회 (DISTINCT 불필요)
중간 테이블에서 연관 엔티티를 조회할 때는 각 행이 서로 다른 객체다.
@Entity
public class OrderMember { // 이 엔티티를 조회
@ManyToOne
private Member member;
}
데이터:
orderId | memberId
-------------------
1 | 101
1 | 102
1 | 103
결과:
// 3개의 서로 다른 객체 → 중복 없음!
[
OrderMember(1, 101),
OrderMember(1, 102),
OrderMember(1, 103)
]
2. OneToMany 조회 (DISTINCT 필요)
반대로 조회하면 부모 객체가 중복된다.
@Entity
public class Order { // 이 엔티티를 조회
@OneToMany
private List<OrderMember> orderMembers;
}
@Query("SELECT o FROM Order o " +
"JOIN FETCH o.orderMembers " +
"WHERE o.orderId = :orderId")
문제:
// Order 객체가 3번 중복됨!
[
Order@1001, // orderId=1
Order@1002, // orderId=1 (중복!)
Order@1003 // orderId=1 (중복!)
]
해결:
@Query("SELECT DISTINCT o FROM Order o " +
"JOIN FETCH o.orderMembers " +
"WHERE o.orderId = :orderId")
한눈에 보는 비교표
| 조회 방향 | 반환 타입 | DISTINCT | 이유 |
|---|---|---|---|
| N → 1 (ManyToOne) | List<중간테이블> |
불필요 | 각 레코드가 다름 |
| 1 → N (OneToMany) | List<부모엔티티> |
필요 | 부모가 자식 수만큼 중복 |
결론
내 코드는 ManyToOne 방향으로 중간 테이블을 조회하므로 DISTINCT가 필요 없다.
- 각 행이 서로 다른 (orderId, memberId) 조합
- 중복 발생하지 않음
- DISTINCT를 추가하면 오히려 불필요한 메모리 연산만 발생
'개발하다 > Spring' 카테고리의 다른 글
| Spring Data JPA Native Query에서 만난 InvalidDataAccessApiUsageException (0) | 2025.10.21 |
|---|---|
| DB부터 시작하는 JPA Entity 매핑 정리 (0) | 2025.10.20 |
| Spring에서 실행 시간 측정하기 (0) | 2025.10.17 |
| @ControllerAdvice와 @ExceptionHandler로 전역 예외 처리하기 (0) | 2025.10.16 |
| MyBatis에서 JPA로 점진적 마이그레이션하기 (0) | 2025.10.12 |