[Spring] 쇼핑몰 3- 상품 수정

춤인형의 개발일지·2025년 2월 27일

Spring실습

목록 보기
37/40

상품 수정은 상품들도 수정이 되고, 상품의 옵션도 수정이 되어야 한다.

첫번째 방법

내가 시도한 방법은 어차피 상품 옵션은 서브 옵션을 알고 있으니까, (관계를 이미 설정을 해놨으니까) 상품 옵션을 상품과 오브젝트끼리 관계를 맺어줘야 된다고 생각했다. 그래서 아래와 같은 코드가 만들어졌다.

@Transactional
    public ProductUpdateResponse update(Admin admin, Long productId, ProductUpdateRequest productUpdateRequest) {
        adminRepository.findById(admin.getId())
                .orElseThrow(() -> new NoSuchElementException("해당 관리자가 아닙니다."));

        Product product = productRepository.findById(productId)
                .orElseThrow(() -> new NoSuchElementException("해당 상품이 없습니다."));

        List<ProductOption> productOptions = productUpdateRequest.options()
                .stream()
                .map(option -> new ProductOption(
                        option.optionName(),
                        product
                )).toList();
        
        product.update(
                productUpdateRequest.productName(),
                productUpdateRequest.price(),
                productUpdateRequest.description(),
                productUpdateRequest.productCondition(),
                productOptions
        );

        return new ProductUpdateResponse(
                productId, product.getName(),
                product.getPrice(),
                product.getDescription(),
                product.getProductCondition(),
                convertToOptionGroup(product.getOptions()),
                product.getUpdatedAt());
    }

이거는 지금 최상위 상품 옵션만 상품을 참조하는 코드이다. 나는 어떻게 생각했냐면, 하위 옵션과 상위 옵션은 서로가 알고 있으니까 내가 굳이 설정해줄 필요가 없다고 생각했다. 근데 이렇게 하고 테스트코드를 짜서 돌려보니까 아래 코드처럼 색상의 옵션들이 다 사라져버렸다. 분명 요청 보낸거까지는 잘 됐는데, 응답을 받을 때는 옵션들이 다 사라져버렸다.

{
    "id": 1,
    "productName": "수정된 상품",
    "price": 27000,
    "description": "수정된 상품 설명",
    "productCondition": "New",
    "options": [
        {
            "optionName": "색상",
            "optionValues": [
                
            ],
            "subOptions": [
                
            ]
        }
    ],
    "updateAt": "2025-02-27T17:39:19.816386"

❓왜? 왜 사라져?
왜냐면 관계 설정은 관계설정이고, 실제로 오브젝트 관계를 맺어줘야한다. 그렇게 안하면 관계를 맺는게 의미가 없는거니까..
관계를 맺는다고 실제로 적용되는건 아니다. 따라서 관계를 맺어줘라~!

❓실제 코드에서 관계를 어떻게 맺는가?
이거는 사실 .map써서 그 안에 옵션과 옵션의 옵션을 넣어주면 된다. 근데 뭔가 여기까지 오기가 어려웠음

그래서 관계를 맺어준 코드는 아래와 같다.

List<ProductOption> productOptions = new ArrayList<>();

        // 옵션그룹과 옵션값 처리 (한 번에 처리)
        for (OptionGroup optionGroup : productUpdateRequest.options()) {
            ProductOption option = new ProductOption(optionGroup.optionName(), product);
            ProductOption savedOption = productOptionRepository.save(option);
            productOptions.add(savedOption);

            if (optionGroup.optionValues() != null && !optionGroup.optionValues().isEmpty()) {
                List<ProductOptionSub> optionSubs = optionGroup.optionValues().stream()
                        .map(value -> new ProductOptionSub(
                                value.optionValue(),
                                value.stock(),
                                savedOption))
                        .toList();

                productOptionSubRepository.saveAll(optionSubs);
            }
        }

문제1

상위 옵션의 list값을 하나 만들고, 최상위 옵션을 먼저 저장하고, 옵션의 하위옵션이 만약 있으면, 그 옵션도 옵션 리스트에 넣어줘라 라는 의미이다.
근데 이것도 옵션과 옵션의 관계를 맺으려니까 아예 안됐다....

문제2

그리고 for문 안에 for문, 2중 중첩이 되면 성능이 좋지 않다. 성능 상에도 좋지 않고, 문제가 해결되지 않는다면 분리 작업이 필요하다.

그래서! endpoint를 바꾸기로 결정했다! 다음 포스트에서 설명하겠다!

0개의 댓글