본문 바로가기

카테고리 없음

24.03.25 익셉션이 나오지 않던 문제, lazy를 dto를 받아오도록 하기

@Transactional
    override fun createReview(
        productId: Long,
        socialUser: UserPrincipal,
        createReviewRequest: CreateReviewRequest,
    ): ReviewResponse {
//        validateRating(createReviewRequest.rating)
        val user =
            socialUserRepository.findByEmail(socialUser.email)
               

        val product =
            productRepository.findByIdAndDeletedAtIsNull(productId)
                .orElseThrow { ModelNotFoundException("Product not found or deleted", productId) }

        orderRepository.findByProductIdAndSocialUserId(productId, user.id)
            .orElseThrow { ModelNotFoundException("주문내역을 확인할 수 없습니다", productId) }

        val review = createReviewRequest.toReview(product, user)

        val savedReview = reviewRepository.save(review)
        return ReviewResponse.toReviewResponse(savedReview)
    }

여기에서 틀린 상품의 아이디를 입력을 해도 Product not found or deleted가 나오지 않았던 이유는 알고보니, 

val user =
    socialUserRepository.findByEmail(socialUser.email)
        .orElseThrow { ModelNotFoundException("User not found", socialUser.id) }

이런식으로  소셜유저에도 익셉션을 입력해야만 제대로 인식이 되는거란걸 알았다.

 

그리고 재고가 0인데도 주문이 되는 현상도 있었는데,

@Transactional
    override fun createOrder(
        userId: Long,
        productId: Long,
        quantity: Int,
        address: String,
        phoneNumber: String,
    ): ResponseOrderDto {
        val findUser = socialUserRepository.findByIdOrNull(userId) ?: throw Exception("존재하지 않는 유저입니다")
        val findProduct =
            productRepository.findByIdAndDeletedAtIsNull(productId).orElseThrow { Exception("존재하지 않는 상품입니다") }
        val stockCheck = productStockRepository.findByProduct(findProduct)

        if (stockCheck!!.stock < 0 && stockCheck.stock <= quantity) throw Exception("재고가 모자랍니다. 판매자에게 문의해주세요")

이부분에서 stockCheck!!.stock < 0 && stockCheck.stock <= quantity가 아니라 

if (stockCheck!!.stock <= quantity) throw Exception("재고가 모자랍니다. 판매자에게 문의해주세요")

이래야만 0일때 주문이 안된다는걸 확인했다.

 

그 다음은 lazy일때 검색이 되지않는 문제를 수정했다. 그동안에는 eager로 미봉책으로 막아놨는데, 여러 방법중 dto가 가장 문제점이 적은 방법이라고 판단했기에 그걸 하기로 했다.

 

Hibernate5Module을 사용하는것도 방법이지만, dto는 이미 만들어놨기 때문에 활용하기도 쉽다는 이유도 있었다.

 

@Transactional
override fun searchProducts(
    keyword: String,
    pageable: Pageable,
): Page<ProductSearchResponse> { 원래 이부분이 Page<Product>였던걸 dto에서 받아오도록 하고
    saveSearchHistory(keyword) 

    val productPage = searchProductRepository.findByTitleContaining(keyword, pageable)

    return productPage.map { product ->
        ProductSearchResponse( 이렇게 dto에 해당하는 부분을 보여준다
            productId = product.id!!,
            title = product.title,
            content = product.content,
            imageUrl = product.imageUrl,
            price = product.price,
            ratingAverage = product.ratingAverage,
            likes = product.likes
        )
    }
}

 

@Transactional
override fun searchReviews(
    keyword: String,
    pageable: Pageable,
): Page<ReviewSearchResponse> {
    saveSearchHistory(keyword)

    val reviewsPage = searchReviewRepository.findReviewsByTitleContaining(keyword, pageable)

    return reviewsPage.map { review ->
        ReviewSearchResponse(
            reviewId = review.id!!,
            productId = review.product.id!!,
            title = review.title,
            content = review.content,
            imageUrl = review.imageUrl,
            name = review.socialUser.nickname,
            likes = review.likes,
        )
    }
}

리뷰도 똑같은 방법으로 만들어준다.

fun searchProductsByLikes(pageable: Pageable): List<ProductSearchResponse>

fun searchReviewsByLikes(pageable: Pageable): List<ReviewSearchResponse>

서비스도 물론 이렇게 dto를 받도록 수정하면 된다. 해놓고보니 간단했지만, 이걸 시도할땐 어려웠었다.