TIL + 트러블슈팅

효준·2024년 12월 2일
0

12월 2일 월요일
AM 알고리즘 풀이
PM 개인 공부, 과제 보강

💡 Today Issue

JPQL 사용시 Optional<Object[]> 사용시 문제점

🤔 나의 생각 + 배운 것

JPQL 사용시 Optional<Object[]> 사용시 문제점

Service

  User user =  userRepository.findById(userId).orElseThrow(() -> new IllegalArgumentException(String.valueOf(ErrorCode.BAD_REQUEST_ERROR)));
        // 쿼리 실행: userId에 맞는 count와 totalAmountInKrw 값을 가져옴
        Optional<Object[]> rawResult = exchangeRepository.findExchangeCurrenciesByUser(user);

        // 결과가 없을 경우 빈 DTO 반환
        if (rawResult.isEmpty()) {
            throw new IllegalArgumentException("No exchange data found for user with ID: " + userId);
        }

        // Object[] 배열에서 결과 추출
        Object[] result = rawResult.get();
        Long count = ((Number) result[0]).longValue(); // count 값
        Long totalAmountInKrw = ((BigDecimal) result[1]).longValue(); // totalAmountInKrw 값

        // TotalExchangeResponsDto로 변환하여 반환
        return new TotalExchangeResponsDto(count, totalAmountInKrw);

Repository

    @Query("select count(ec.id) count, SUM(ec.amountInKrw) totalAmountInKrw from ExchangeCurrency ec where ec.user =:user group by ec.user")
    Optional<Object[]> findExchangeCurrenciesByUser(@Param("user") User user);

userId를 받아 해당 유저의 모든 환전 요청 및 환전 한 금액을 반환하는 기능을 구현하고 있었다.

원인 추론

		// Object[] 배열에서 결과 추출
        Object[] result = rawResult.get();
//        Long count = ((Number) result[0]).longValue(); // count 값
        Long count = 1L;
        Long totalAmountInKrw = ((BigDecimal) result[1]).longValue(); // totalAmountInKrw 값

위와 같이 잠시 count에 다른 값을 주고 totalAmountInKrw만 출력해보려던 도중 인덱스에 하나의 값만 들어가 있다는 오류를 반환하였다.

쿼리문은 이미 검증을 하고 난 후여서 분명 count 값이 result[0]에 있어야 하고 1번째 인덱스에 totalAmountInKrw값이 있어야했다.

해결 방안

        List<Object[]> rawResult = exchangeRepository.findExchangeCurrenciesByUser(user);

        Object[] result = rawResult.get(0);

        Long count = ((Long) result[0]); // count 값
        BigDecimal totalAmountInKrw = ((BigDecimal) result[1]); // totalAmountInKrw 값

Optional로 감싸고 있던 Object[]을 List로 감싸서 반환하도록 Repository를 수정하였다.
이후 .get으로 배열을 받아 사용하였다.

Optional로 감싸서 받으면 JPQL의 반환 하는 데이터를 count, totalAmountInKrw로 두개를 받아야하는데 이것을 한번에 받기 때문에 인덱스를 하나만 반환하는 것이였다.

Object[]로 받을거면 하나의 데이터여도 List로 받는게 좋고 JPQL이든 Query든 Dto를 활용하면 이전에 query로 반환된 값도 검증할 수 있다고 하니 Dto를 사용하는것도 좋은 방법 같다.

결과 확인

🕐회고

아직도 어려운 부분이 많고 경험 할수록 많은걸 알아 가는 것 같다.

profile
사진은 캣타워가 생겨 포효하는 고양이입니다.

0개의 댓글

관련 채용 정보