Skip to content

Commit 9bb9132

Browse files
authored
주문 상세조회 에러 수정 (#398)
1 parent a8ae603 commit 9bb9132

File tree

3 files changed

+35
-20
lines changed

3 files changed

+35
-20
lines changed

src/main/java/com/back/domain/order/order/repository/OrderRepository.java

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,19 +19,20 @@ public interface OrderRepository extends JpaRepository<Order, Long> {
1919
// 사용자별 주문 목록 (페이징)
2020
Page<Order> findByUserOrderByOrderDateDesc(User user, Pageable pageable);
2121

22-
// 사용자별 주문 목록 조회 - N+1 방지를 위한 Fetch Join
22+
// 사용자별 주문 목록 조회 - N+1 방지를 위한 Fetch Join (NORMAL + FUNDING)
2323
@Query("SELECT DISTINCT o FROM Order o " +
2424
"LEFT JOIN FETCH o.orderItems oi " +
2525
"LEFT JOIN FETCH oi.product p " +
26+
"LEFT JOIN FETCH oi.funding f " +
2627
"WHERE o.user = :user " +
2728
"ORDER BY o.orderDate DESC")
2829
List<Order> findByUserWithOrderItemsAndProducts(@Param("user") User user, Pageable pageable);
2930

30-
// 주문 상세 조회 - Fetch Join (상품 정보만)
31-
@Query("SELECT o FROM Order o " +
31+
// 주문 상세 조회 - Fetch Join (상품 정보 + 펀딩 정보)
32+
@Query("SELECT DISTINCT o FROM Order o " +
3233
"LEFT JOIN FETCH o.orderItems oi " +
3334
"LEFT JOIN FETCH oi.product p " +
34-
"LEFT JOIN FETCH p.user " +
35+
"LEFT JOIN FETCH oi.funding f " +
3536
"WHERE o.id = :orderId")
3637
Optional<Order> findByIdWithOrderItems(@Param("orderId") Long orderId);
3738

@@ -68,24 +69,26 @@ Page<Order> findOrdersForDashboard(
6869
);
6970

7071
/**
71-
* 대시보드용 주문 목록 조회 - 상품명 정렬용
72+
* 대시보드용 주문 목록 조회 - 상품명 정렬용 (N+1 방지)
7273
* 상품명 정렬 시 각 주문의 상품 중 이름이 가장 빠른 상품(ㄱ에 가까운)을 기준으로 정렬
7374
* 1차 정렬: 상품명 (ASC/DESC)
7475
* 2차 정렬: 주문 날짜 (최신순)
7576
*/
76-
@Query("SELECT o FROM Order o " +
77-
"LEFT JOIN o.orderItems oi " +
77+
@Query("SELECT DISTINCT o FROM Order o " +
78+
"LEFT JOIN FETCH o.orderItems oi " +
79+
"LEFT JOIN FETCH oi.product p " +
80+
"LEFT JOIN FETCH oi.funding f " +
7881
"WHERE o.user = :user " +
7982
"AND o.status IN (com.back.domain.order.order.entity.OrderStatus.PAYMENT_COMPLETED, " +
8083
" com.back.domain.order.order.entity.OrderStatus.PREPARING_SHIPMENT, " +
8184
" com.back.domain.order.order.entity.OrderStatus.SHIPPING, " +
8285
" com.back.domain.order.order.entity.OrderStatus.DELIVERED) " +
8386
"AND (:keyword IS NULL OR :keyword = '' OR " +
8487
" EXISTS (SELECT 1 FROM OrderItem oi2 WHERE oi2.order = o AND oi2.product.name LIKE CONCAT('%', :keyword, '%'))) " +
85-
"AND oi.product.name = (SELECT MIN(oi3.product.name) FROM OrderItem oi3 WHERE oi3.order = o) " +
88+
"AND p.name = (SELECT MIN(p2.name) FROM OrderItem oi3 JOIN oi3.product p2 WHERE oi3.order = o) " +
8689
"ORDER BY " +
87-
"CASE WHEN :direction = 'ASC' THEN oi.product.name END ASC, " +
88-
"CASE WHEN :direction = 'DESC' THEN oi.product.name END DESC, " +
90+
"CASE WHEN :direction = 'ASC' THEN p.name END ASC, " +
91+
"CASE WHEN :direction = 'DESC' THEN p.name END DESC, " +
8992
"o.orderDate DESC")
9093
Page<Order> findOrdersForDashboardSortedByProductName(
9194
@Param("user") User user,
@@ -95,24 +98,26 @@ Page<Order> findOrdersForDashboardSortedByProductName(
9598
);
9699

97100
/**
98-
* 주문 상세 정보 조회 (OrderItem, Product 포함)
101+
* 주문 상세 정보 조회 (OrderItem, Product, Funding 포함)
99102
* 대시보드에서 페이징 후 실제 데이터를 가져올 때 사용
100103
* Product의 Images는 @BatchSize로 최적화 (N+1 방지)
101104
*/
102105
@Query("SELECT DISTINCT o FROM Order o " +
103106
"LEFT JOIN FETCH o.orderItems oi " +
104107
"LEFT JOIN FETCH oi.product p " +
108+
"LEFT JOIN FETCH oi.funding f " +
105109
"WHERE o.id IN :orderIds")
106110
List<Order> findOrdersWithDetailsById(@Param("orderIds") List<Long> orderIds);
107111

108112
/**
109-
* 작가별 주문 목록 조회 (작가용 대시보드)
113+
* 작가별 주문 목록 조회 (작가용 대시보드) - N+1 방지
110114
* 작가가 판매한 상품의 주문만 조회
111115
* 주문 상태, 키워드 검색, 날짜 범위 필터 지원
112116
*/
113117
@Query("SELECT DISTINCT o FROM Order o " +
114-
"JOIN o.orderItems oi " +
115-
"JOIN oi.product p " +
118+
"LEFT JOIN FETCH o.orderItems oi " +
119+
"LEFT JOIN FETCH oi.product p " +
120+
"LEFT JOIN FETCH oi.funding f " +
116121
"WHERE p.user.id = :artistId " +
117122
"AND (:status IS NULL OR o.status = :status) " +
118123
"AND (:keyword IS NULL OR :keyword = '' OR " +

src/main/java/com/back/domain/order/order/service/OrderService.java

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ public Page<OrderResponseDto> getOrderList(User user, Pageable pageable) {
105105
/**
106106
* 주문 상세 조회
107107
*/
108+
@Transactional(readOnly = true)
108109
public OrderResponseDto getOrderDetail(Long orderId, User user) {
109110
Order order = orderRepository.findByIdWithOrderItems(orderId)
110111
.orElseThrow(() -> new IllegalArgumentException("주문을 찾을 수 없습니다."));
@@ -572,11 +573,20 @@ private String getProductThumbnailUrl(Product product) {
572573
* 펀딩 썸네일 이미지 URL 조회
573574
*/
574575
private String getFundingThumbnailUrl(Funding funding) {
575-
return funding.getImages().stream()
576-
.filter(image -> "THUMBNAIL".equals(image.getFileType().name()))
577-
.findFirst()
578-
.map(image -> image.getFileUrl())
579-
.orElse(funding.getImageUrl()); // 썸네일이 없으면 메인 이미지 사용
576+
try {
577+
// Funding.images는 LAZY 로딩이므로 안전하게 접근
578+
if (funding.getImages() != null && !funding.getImages().isEmpty()) {
579+
return funding.getImages().stream()
580+
.filter(image -> "THUMBNAIL".equals(image.getFileType().name()))
581+
.findFirst()
582+
.map(image -> image.getFileUrl())
583+
.orElse(funding.getImageUrl()); // 썸네일이 없으면 메인 이미지 사용
584+
}
585+
} catch (Exception e) {
586+
// LAZY 로딩 실패 시 메인 이미지 사용
587+
log.warn("Funding 이미지 로딩 실패, 메인 이미지 사용: fundingId={}", funding.getId());
588+
}
589+
return funding.getImageUrl(); // 기본 이미지 사용
580590
}
581591

582592
/**

src/main/java/com/back/global/s3/S3Service.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ public List<UploadResultResponse> uploadFile(MultipartFile file, String folder,
108108
results.add(new UploadResultResponse(url, type, s3Key, originalFilename));
109109

110110
if (category == FileCategory.IMAGE && type == FileType.MAIN) {
111-
byte[] thumbBytes = resizeImageSafe(file.getBytes(), 300, 300, extension);
111+
byte[] thumbBytes = resizeImageSafe(file.getBytes(), 300, 400, extension);
112112
// 썸네일 S3 Key 생성
113113
String thumbKey = folder + "/thumbnail-" + UUID.randomUUID() + "." + extension;
114114
//S3에 썸네일 이미지 업로드

0 commit comments

Comments
 (0)