제품 연관관계 수정

뚜우웅이·2025년 5월 17일

캡스톤 디자인

목록 보기
20/35

제품 연관관계 수정

현재 문제점

  • 외래 키 제약조건으로 인해 연관 데이터(product_view_counts 등)가 있으면 제품 삭제가 실패한다.
  • 제품 이미지 파일이 서버 파일 시스템에 그대로 남아있어 공간 낭비가 발생한다.

해결 방안

  • ProductService에 트랜잭션 처리된 deleteProduct 메서드를 구현하여 연관 데이터를 모두 삭제한다..
  • 이미지 파일도 함께 삭제하는 로직을 추가한다.

ProductManagementServie

    // 상품 삭제
    @Transactional
    public void deleteProduct(Long userId, Long productId) {
        Product product = getProductWithSellerCheck(productId, userId);
        
        // 1. 관련 조회수 데이터 삭제
        viewCountRepository.deleteByProductId(productId);
        
        // 2. 관련 위시리스트 데이터 삭제
        wishlistRepository.deleteByProductId(productId);
        
        // 3. 리뷰 데이터 삭제 (비즈니스 요구사항에 따라)
        reviewRepository.findByProduct(product).ifPresent(reviewRepository::delete);
        
        // 4. 이미지 파일 삭제를 위한 URL 수집
        List<String> imageUrls = new ArrayList<>();
        List<String> thumbnailUrls = new ArrayList<>();
        
        // 이미지 URL 수집
        for (ProductImage image : product.getImages()) {
            imageUrls.add(image.getImageUrl());
            thumbnailUrls.add(image.getThumbnailUrl());
        }
        
        try {
            // 5. 상품 삭제 (이미지 엔티티도 cascade로 함께 삭제됨)
            productRepository.delete(product);
            
            // 6. 파일 시스템에서 이미지 파일 삭제
            for (String url : imageUrls) {
                fileStorageService.deleteFile(url);
            }
            for (String url : thumbnailUrls) {
                fileStorageService.deleteFile(url);
            }
            
            log.info("상품 삭제 완료: 상품 ID {}, 판매자 ID {}", productId, userId);
        } catch (Exception e) {
            log.error("상품 삭제 중 오류 발생: 상품 ID {}, 원인: {}", productId, e.getMessage(), e);
            throw new ProductException.ProductDeletionException(e.getMessage());
        }
    }

상품 삭제 로직 개선

  • ProductManagementServicedeleteProduct 메서드를 완전히 재구현했다.
  • 관련된 모든 데이터(조회수, 위시리스트, 리뷰 등)를 순서대로 삭제한다.
  • 상품 및 이미지 엔티티를 삭제한 후, 파일 시스템에서도 이미지 파일을 삭제한다.

ProductViewCountRepository

    @Modifying
    @Query("DELETE FROM ProductViewCount pvc WHERE pvc.product.id = :productId")
    void deleteByProductId(@Param("productId") Long productId);

productId에 해당하는 상품의 조회수 기록(ProductViewCount) 을 삭제하는 쿼리다.

ProductWishlistRepository

    @Modifying
    @Query("DELETE FROM ProductWishlist pw WHERE pw.product.id = :productId")
    void deleteByProductId(@Param("productId") Long productId);

ProductException


    public static class ProductDeletionException extends ProductException {
        public ProductDeletionException(String message) {
            super("상품 삭제 중 오류가 발생했습니다: " + message, HttpStatus.INTERNAL_SERVER_ERROR, "PRODUCT_DELETION_FAILED");
        }
    }
profile
공부하는 초보 개발자

0개의 댓글