diff --git a/src/main/java/com/example/petree/domain/adopter/domain/Review.java b/src/main/java/com/example/petree/domain/adopter/domain/Review.java index bee5aef..d7ee769 100644 --- a/src/main/java/com/example/petree/domain/adopter/domain/Review.java +++ b/src/main/java/com/example/petree/domain/adopter/domain/Review.java @@ -53,6 +53,6 @@ public class Review { @JoinColumn(name = "adopter_id") private Adopter adopter; - @OneToMany(mappedBy = "review", cascade = CascadeType.ALL, orphanRemoval = true) + @OneToMany(mappedBy = "review", cascade = CascadeType.ALL, fetch = FetchType.LAZY) private List images = new ArrayList<>(); } diff --git a/src/main/java/com/example/petree/domain/adopter/domain/ReviewImgFile.java b/src/main/java/com/example/petree/domain/adopter/domain/ReviewImgFile.java index 8b148b1..f732641 100644 --- a/src/main/java/com/example/petree/domain/adopter/domain/ReviewImgFile.java +++ b/src/main/java/com/example/petree/domain/adopter/domain/ReviewImgFile.java @@ -35,7 +35,7 @@ public class ReviewImgFile { private String originalFileName; private String fileName; private String fileUrl; - @ManyToOne(fetch = FetchType.LAZY) + @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL) @JoinColumn(name = "review_id") private Review review; } diff --git a/src/main/java/com/example/petree/domain/adopter/dto/ReviewDto.java b/src/main/java/com/example/petree/domain/adopter/dto/ReviewDto.java index 6d0047c..ce57c2a 100644 --- a/src/main/java/com/example/petree/domain/adopter/dto/ReviewDto.java +++ b/src/main/java/com/example/petree/domain/adopter/dto/ReviewDto.java @@ -69,6 +69,8 @@ public static class ReviewUpdateRequestDto { @Length(max = 3000, message = "내용은 최대 3000자까지 입력 가능합니다.") @Schema(description = "내용", example = "정성스럽게 키우곘습니다!") private String content; + @Schema(description = "이미지 삭제 여부") + private boolean deleteImages; @NotEmpty(message = "이미지는 필수 입력값입니다.") @Schema(description = "분양 후기 이미지 리스트") @JsonSerialize(using = ToStringSerializer.class) diff --git a/src/main/java/com/example/petree/domain/adopter/repository/ReviewRepository.java b/src/main/java/com/example/petree/domain/adopter/repository/ReviewRepository.java index ced5d45..5fd29a3 100644 --- a/src/main/java/com/example/petree/domain/adopter/repository/ReviewRepository.java +++ b/src/main/java/com/example/petree/domain/adopter/repository/ReviewRepository.java @@ -2,7 +2,11 @@ import com.example.petree.domain.adopter.domain.Review; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; +import org.springframework.transaction.annotation.Transactional; /** * packageName : com.example.petree.domain.adopter.repository @@ -18,4 +22,8 @@ @Repository public interface ReviewRepository extends JpaRepository, ReviewRepositoryCustom { + @Transactional + @Modifying + @Query("DELETE FROM ReviewImgFile WHERE review = :review") + void deleteReviewImgFilesByReview(@Param("review") Review review); } diff --git a/src/main/java/com/example/petree/domain/adopter/service/ReviewService.java b/src/main/java/com/example/petree/domain/adopter/service/ReviewService.java index b53847f..40c891b 100644 --- a/src/main/java/com/example/petree/domain/adopter/service/ReviewService.java +++ b/src/main/java/com/example/petree/domain/adopter/service/ReviewService.java @@ -14,6 +14,7 @@ import com.example.petree.global.util.FileUtil; import com.example.petree.global.util.S3Util; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.Pageable; @@ -39,6 +40,7 @@ @Service @RequiredArgsConstructor +@Slf4j public class ReviewService { private final ReviewRepository reviewRepository; @@ -67,10 +69,26 @@ public void update(ReviewDto.ReviewUpdateRequestDto request, Review review, Adop review.setContent(request.getContent()); } + if (request.isDeleteImages()) { + deleteReviewImages(review); + } + + updateReviewImages(request.getReviewImgFiles(), review); + + // 리뷰 저장 + reviewRepository.save(review); + } + + private void deleteReviewImages(Review review) { + // 기존 이미지 삭제 + reviewRepository.deleteReviewImgFilesByReview(review); + } + + private void updateReviewImages(List newImages, Review review) { // 이미지 리스트를 수정하려면 이전 이미지 리스트를 제거하고 새로운 이미지를 추가 - if (request.getReviewImgFiles() != null && !request.getReviewImgFiles().isEmpty()) { - List newImages = new ArrayList<>(); - for (MultipartFile file : request.getReviewImgFiles()) { + List images = new ArrayList<>(); + if (newImages != null && !newImages.isEmpty()) { + for (MultipartFile file : newImages) { String originalFilename = file.getOriginalFilename(); String fileName = UUID.randomUUID().toString() + "." + fileUtil.extractExt(originalFilename); String fileUrl = s3Util.upload(file, "review-img", fileName); @@ -79,17 +97,19 @@ public void update(ReviewDto.ReviewUpdateRequestDto request, Review review, Adop .originalFileName(file.getOriginalFilename()) .fileName(fileName) .fileUrl(fileUrl) + .review(review) .build(); - reviewImgFileRepository.save(imgFile); - newImages.add(imgFile); + images.add(imgFile); } - review.setImages(newImages); + // 이미지 저장 및 리뷰에 새로운 이미지 설정 + review.setImages(images); } - - reviewRepository.save(review); } + + + /** * @author 박수현 * @date 2023-08-29 diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 3dcdad9..910fea0 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -10,6 +10,8 @@ spring: # spring banner off main: banner-mode: "off" + jpa: + show-sql: true mvc: pathmatch: @@ -39,5 +41,12 @@ springdoc: - com.example.petree.domain.breeder.controller - com.example.petree.domain.main_breed.controller - com.example.petree.domain.basic_test.controller + - com.example.petree.domain.adopter.controller + +logging: + level: + org: + hibernate: + SQL: DEBUG