오류 및 문제점
1. nativeQuery 실행시 Like 연산 및 select 결과
- 문제점: SQL 쿼리로는 실행이 되는데 SpringBoot 실행시 빈 리스트가 나온다.
- Like 연산 실행시 %?%가 나와야 하는데 %:value%로 쿼리가 실행된다.
- select seller_no, address, group_name, end_date 실행시 Unknown label 'address' 에러가 발생한다.
- 해결 방안: CONCAT 함수를 이용해 문자열을 만든다. Seller를 받은 후 원하는 DTO 형태에 맞게 변환한다.
@Query(value = "SELECT * "
+ "FROM seller "
+ " JOIN product_group "
+ " ON seller.product_group_no = product_group.product_group_no "
+ " LEFT OUTER JOIN matching "
+ " ON seller.seller_no = matching.seller_no "
+ "WHERE seller.seller_no IN (SELECT seller.seller_no "
+ " FROM exports "
+ " JOIN export_product "
+ " ON exports.export_no = export_product.export_no "
+ " RIGHT OUTER JOIN seller "
+ " ON exports.seller_seller_no = seller.seller_no "
+ " WHERE IFNULL(order_status, '') LIKE if(:exportCnt > 0, '출고완료', '%') "
+ " GROUP BY seller.seller_no "
+ " HAVING COUNT(*) >= :exportCnt) "
+ "AND product_group.group_name LIKE CONCAT('%', :groupName, '%') "
+ "AND seller.address LIKE CONCAT('%', :address, '%') "
+ "AND IFNULL(end_date, SYSDATE()) <= DATE_ADD(SYSDATE(), INTERVAL :contractPeriod MONTH)", nativeQuery = true)
public Page<Seller> findByMatchingCondition(@Param("groupName") String groupName, @Param("address")String address,
@Param("exportCnt")int exportCnt, @Param("contractPeriod")int contractPeriod, Pageable pageable);
2. The dependencies of some of the beans in the application context form a cycle
- 문제점: Service에서 양방향으로 서로의 Service를 참조한다.
- 해결 방안: 처음 설계부터 양방향 참조가 이루어지지 않도록 잘 설계해야 한다. 지금은 남은 시간 내 수정이 불가능하기 때문에 하나의 서비스에서는 Repository를 선언하는 방법으로 해결한다. 다른 게시글을 참고해보면 @Lazy를 사용해 임시방편으로 해결하는 방법도 있다고 한다.
private final SellerRepository sellerRepo;
private final OrderRepository orderRepo;
private final ImportsRepository importsRepo;
private final ExportProductRepository exportProductRepository;
private final MatchingRepository matchingRepository;
진행 상황
1. 상품군, 세부 상품군 문자열 리스트로 변경
- 전해주는 값이 하나밖에 없기 때문에 문자열 리스트로 반환한다.
public List<String> findAll() {
List<String> productGroupNames = new ArrayList<>();
List<ProductGroup> productGroups = productGroupRepository.findAll();
for(ProductGroup productGroup : productGroups) {
productGroupNames.add(productGroup.getGroupName());
}
return productGroupNames;
}
2. 매칭 조건에 따른 화주사 검색
public MatchingSellerListDTO searchingSellerByCondition(MatchingConditionDTO matchingConditionDTO) {
List<MatchingDTO> matchingSellerDTOs = new ArrayList<>();
Page<Seller> findedSellers = sellerService.findByMatchingCondition(matchingConditionDTO);
for(Seller findedSeller : findedSellers) {
MatchingDTO matchingSeller = findedSeller.toMatchingSellerDTO(matchingRepository.findBySeller_SellerNo(findedSeller.getSellerNo()));
matchingSellerDTOs.add(matchingSeller);
}
MatchingSellerListDTO matchingSellerListDTO = MatchingSellerListDTO
.builder()
.totalPage(findedSellers.getTotalPages())
.matchingCompanies(matchingSellerDTOs)
.build();
return matchingSellerListDTO;
}
3. 화주사 상세 조회
public SellerDTO sellerDetail(Long sellerNo) {
Seller seller = sellerRepo.findById(sellerNo).orElse(null);
Long sales = exportProductRepository.getSalesCountOfYear(sellerNo, Integer.parseInt(TimestampUtil.getPattern("yyyy")) - 1);
Long exportCnt = exportProductRepository.getSalesCountOfYear(sellerNo, Integer.parseInt(TimestampUtil.getPattern("yyyy")) - 1);
Matching matching = matchingRepository.findBySeller_SellerNo(sellerNo);
MatchingDTO matchingDTO = null;
if(matching != null) {
matchingDTO = MatchingDTO
.builder()
.companyName(matching.getWarehouse().getThreePL().getCompanyName())
.endDate(TimestampUtil.convertTimestampToDate(matching.getEndDate()))
.location(matching.getWarehouse().getLocation())
.productGroup(matching.getWarehouse().getThreePL().getProductGroup().getGroupName())
.build();
}
return seller.toSellerDTO(matchingDTO, sales, exportCnt);
}
참고 자료