본문 바로가기
Spring

[TIL] 240204 코드 리뷰/프로젝트 복습 Category

by studymode 2024. 2. 4.

새로 배운 것/ 복습:

 

map

public List<CategoryResponseDto> getCategories() {
  List<Category> categoryList = categoryRepository.findAll();
  return categoryList.stream().map(CategoryResponseDto::new).toList();
}

  - map을 이용하여 쉽고 깔끔하게 entity로 된 list를 dto로 된 리스트로 변경

 

 

IOException

//카테고리 수정
@Secured(Authority.ADMIN)
@PatchMapping("/{categoryId}")
public ResponseEntity<ApiResponse> updateCategory(
    @RequestParam MultipartFile image,
    @RequestPart("data") CategoryRequestDto requestDto,
    @PathVariable Long categoryId) throws IOException {
  CategoryResponseDto categoryResponseDto = categoryService.updateCategory(requestDto, categoryId,
      image);
  return ResponseEntity.status(HttpStatus.OK)
      .body(new ApiResponse("카테고리 수정 성공", HttpStatus.OK.value(), categoryResponseDto));
}

-  다른 exception은 직접 만든 ApiException을 쓰기로 통일했는데

    여기서는 이미지 파일이 있어, IOException을 사용해 줬다

-  자바 IOException은 Input/Output 작업 중에 발생할 수 있는 다양한 문제를 나타내는 예외 클래스

파일을 읽거나 쓸 때, 네트워크 연결에 문제가 있을 때, 또는 데이터를 읽는 도중에 문제가 발생할 때 등

-  이, IOException을 사용하면, 해당 메서드에서 파일과 관련된 작업을 수행하는 동안 발생할 수 있는 문제를 적절하게 처리할 수 있다

 

 

Entity 삭제 시 연관관계 entity 삭제

@Transactional
public void deleteCategory(Long categoryId) {

  userRepository.findAllByFirstPreferredCategory_Id(categoryId).stream().forEach(
      User::deleteFirstPreferredCategoryCategory);
  userRepository.findAllBySecondPreferredCategory_Id(categoryId).stream().forEach(
      User::deleteSecondPreferredCategoryCategory);

  reportRepository.findAllByCategory_Id(categoryId).stream().forEach(report -> {
    reportService.deleteReport(categoryId, report.getId());
  });

  productRepository.findAllByCategory_Id(categoryId).stream().forEach(product -> {
    productService.deleteProduct(product.getId());
  });

  Category category = categoryRepository.findCategoryByIdOrElseThrow(categoryId);
  categoryRepository.delete(category);
  s3Manager.deleteAllImageFiles(categoryId.toString(), S3Manager.CATEGORY_DIRECTORY_NAME);
}

Entity 삭제할 때 연관관계 체크

Category는 User, Report, Product와 연관관계를 맺고 있다

카테고리를 삭제하기 전에 entity repository에서 해당 카테고리가 사용됐는지 stream().forEach로 찾아보고, 

있다면 해당 카테고리를 참조하는 다른 entity를 먼저 삭제한다

 

 

Cascade옵션을 사용할 경우 고려해야 할 점을 참고해보면 '통상적으로 권장하는 cascade 범위는, 완전히 개인 소유하는 엔티티일 때, 예를 들어서 게시판과 첨부파일이 있을 때 첨부파일은 게시판 엔티티만 참조하므로, 개인 소유하는 경우에는 사용 가능'이라고 합니다.

출처: https://resilient-923.tistory.com/417

 

이런 이유로 (질문) cascade사용을 조심해야한다고 하는데,

이 코드를 작성한 팀원은 어떤 생각으로 하나씩 직접 삭제한건지 궁금하다!

내일 물어봐야겠다!!

- (답변) 코드를 직관적으로 짜고, 예기치 못한 연관 관계가 삭제될 수 있기 때문 에 그렇게 짰다고 합니다!

 


 

남의 코드 리뷰 후기:

그냥 배운대로 crud를 항상 똑같이 작성했었는데

다른 사람들이 작성한 코드를 보면서 다양하고 더 심플한 방법으로 코드를 짤 수 있다는걸 배웠다

특히 마지막꺼(연관관계 삭제)는 항상 cascade.all로 처리했었는데

저렇게 하나하나 삭제해 주는 코드를 보면서 왜 그랬을까 고민해볼 수 있는 시간이었다

꼼꼼한 팀원답게 코드에서도 하나씩 entity확인하는 꼼꼼함이 보여서

뭔가 신기했다!!!

데이터를 하나하나 소중하게 다루려는 팀원 성격이 그대로 보이는 코드!!!

 

그리고 또 궁금한거는

(질문) Category등록할때 생성자에 한번에 사진이랑 requestDto를 생성하지 않고

requestDto로 먼저 생성하고 사진은 따로 추가하는 식으로 했는지?

- (답변) category에서 사진만 수정하는 updateImage를 만들어야해서

그 메소드를 만든 김에 그렇게 코드를 짰다고 하네요!!!

합쳐서 하나의 매게변수로 보내면 안되는지?

 

내일 물어봐야지~~~