본문 바로가기

코딩공부

2차 프로젝트(EVision) 트러블슈팅

문제 식별
프로그램 설계 상 판매가는 삭제 없이 등록과 수정만 가능했고, 수정 시에는 기존 값을 변경하는 대신 새로운 판매가가 최신 판매가로 등록되었다.
그러나 사용자가 실수로 잘못된 값을 입력했을 경우 이를 되돌릴 방법이 없다는 문제가 있었다. 이를 해결하기 위해 판매가 삭제 기능의 추가해야 하는 상황이 발생했다.
특히 최신 판매가를 삭제하면 나머지 판매가 중 가장 최신 판매가의 종료일자가 9999-12-31로 변경되어야 했다.
이를 구현하기 위해 가장 최신 데이터만 삭제하고 수정하여야 해서 Stack을 사용하려고 했으나, JPA Repository에는 Stack을 바로 저장할 수 없어서 다른 방법을 고민해야 했다.

문제 해결 접근 방법
JPA Repository에서 여러 데이터를 저장하기 위해 주로 사용되는 자료구조는 List와 Set이다. 데이터를 순서대로 저장 및 삭제해야할 상황이므로 List를 사용하여 해결하고자 했다.
삭제요청이 들어오면 해당 판매가의 데이터를 조회하고 최신 데이터를 삭제한 후 남은 데이터 중 가장 최신 데이터의 종료일자를 수정하는 방식으로 해결하고자 했다.

해결사례
우선 삭제하려는 판매가의 Id를 입력받아 해당 판매가가 Repository에 존재하는지, 종료일자가 9999-12-31 인지 확인했다.
이 조건을 확인한 후, 시작일자를 기준으로 역순 정렬하여 최신 데이터가 앞에 오도록 데이터를 정렬했다.
최신 판매가 데이터 하나를 삭제한 후, 남은 데이터가 있다면 가장 최신 판매가의 종료일자를 9999-12-31 로 수정하였다.
위 해결사례의 코드는 아래와 같다.

 @Transactional
    public void deleteSalesPrice(Long salesPriceId) {
        // 삭제할 SalesPrice 찾기
        SalesPrice salesPriceToDelete = salesPriceRepository.findById(salesPriceId)
                .orElseThrow(() -> new BusinessLogicException(ExceptionCode.SALES_PRICE_NOT_FOUND));

        // 삭제하려는 salesPrice의 endDate가 9999-12-31이 아니라면 예외 발생
        if (!salesPriceToDelete.getEndDate().equals(LocalDate.of(9999, 12, 31))) {
            throw new BusinessLogicException(ExceptionCode.INVALID_DELETE_REQUEST);
        }

        List<SalesPrice> previousSalesPrices = salesPriceRepository.findPreviousSalesPrices(
                salesPriceToDelete.getItem().getItemCode(),
                salesPriceToDelete.getCustomer().getCustomerCode(),
                salesPriceToDelete.getStartDate()
        );

        salesPriceRepository.delete(salesPriceToDelete);

        if (!previousSalesPrices.isEmpty()) {
            SalesPrice mostRecentSalesPrice = previousSalesPrices.get(0); // 최신 값 선택
            mostRecentSalesPrice.setEndDate(LocalDate.of(9999, 12, 31)); // EndDate 업데이트
            salesPriceRepository.save(mostRecentSalesPrice);
        }
    }