Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor/#415 글 삭제, 수정시 게시글 이미지의 soft delete를 위해 update문이 중복해서 나지 않도록 수정함 #526

Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,6 @@ public PostImageInfo(final String storeName, final Post post) {
}

public static PostImageInfo of(final ImageInfo imageInfo, final Post post) {
final PostImageInfo postImageInfo = new PostImageInfo(imageInfo.getStoreName(), post);
//post.addPostImageInfo(postImageInfo);
return postImageInfo;
}

public void delete() {
this.deleted = true;
return new PostImageInfo(imageInfo.getStoreName(), post);
}
}
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
package edonymyeon.backend.image.postimage.domain;

import static edonymyeon.backend.global.exception.ExceptionInformation.IMAGE_STORE_NAME_INVALID;
import static edonymyeon.backend.global.exception.ExceptionInformation.POST_IMAGE_COUNT_INVALID;

import edonymyeon.backend.global.exception.EdonymyeonException;
import edonymyeon.backend.image.domain.ImageInfo;
import edonymyeon.backend.post.domain.Post;
import jakarta.persistence.Embeddable;
import jakarta.persistence.OneToMany;
import java.util.ArrayList;
import java.util.List;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.BatchSize;

import java.util.ArrayList;
import java.util.List;

import static edonymyeon.backend.global.exception.ExceptionInformation.IMAGE_STORE_NAME_INVALID;
import static edonymyeon.backend.global.exception.ExceptionInformation.POST_IMAGE_COUNT_INVALID;

@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Getter
@Embeddable
Expand Down Expand Up @@ -53,11 +54,6 @@ private boolean isInvalidImageCount(final Integer imageCount) {
return imageCount > MAX_IMAGE_COUNT;
}

public void addAll(final List<PostImageInfo> imagesToAdd) {
validateImageCount(this.postImageInfos.size() + imagesToAdd.size());
this.postImageInfos.addAll(imagesToAdd);
}

public void add(final PostImageInfo postImageInfo) {
if (this.postImageInfos.contains(postImageInfo)) {
return;
Expand All @@ -72,14 +68,14 @@ private void validateImageAdditionCount() {
}
}

public void update(final List<String> remainedStoreNames, final List<PostImageInfo> newPostImageInfos) {
public List<Long> getImageIdsToDeleteBy(final List<String> remainedStoreNames, final List<PostImageInfo> newPostImageInfos) {
final List<PostImageInfo> imagesToDelete = findImagesToDelete(remainedStoreNames);
int updatedImageCount = this.postImageInfos.size() - imagesToDelete.size() + newPostImageInfos.size();
validateImageCount(updatedImageCount);

imagesToDelete.forEach(PostImageInfo::delete);
postImageInfos.removeAll(imagesToDelete);
postImageInfos.addAll(newPostImageInfos);
return imagesToDelete.stream()
.map(ImageInfo::getId)
.toList();
}

private List<PostImageInfo> findImagesToDelete(final List<String> remainedStoreNames) {
Expand All @@ -93,18 +89,6 @@ private List<PostImageInfo> findImagesToDelete(final List<String> remainedStoreN
return unmatchedPostImageInfos;
}

// todo : 여기 부분 맞게 했나요? 헷갈립니다.
public void delete(final List<PostImageInfo> deletedPostImageInfos) {
// 어쨌든 deleted = false 인 놈들만 가지고 있어야 하니 지워져야 할 녀석들을 리스트에서 뺀다.
this.postImageInfos.removeAll(deletedPostImageInfos);
// 지워져야 하는 녀석들을 soft delete
deletedPostImageInfos.forEach(PostImageInfo::delete);
}

public void deleteAll() {
this.postImageInfos.forEach(PostImageInfo::delete);
}

public boolean isEmpty() {
return this.postImageInfos.isEmpty();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
package edonymyeon.backend.image.postimage.repository;

import edonymyeon.backend.image.postimage.domain.PostImageInfo;
import java.util.List;
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 java.util.List;

public interface PostImageInfoRepository extends JpaRepository<PostImageInfo, Long> {

List<PostImageInfo> findAllByPostId(final Long postId);

@Modifying
@Query("delete from PostImageInfo pi where pi.post.id=:postId")
@Query("update PostImageInfo pi set pi.deleted = true where pi.post.id=:postId")
void deleteAllByPostId(@Param("postId") final Long postId);

@Query(value = "select * from post_image_info", nativeQuery = true)
List<PostImageInfo> findAllImages();
Comment on lines -18 to -19
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

제가 못지운 부분을 지워주셨군요!! 감사드립니당
CommentInfoRepository, ProfileImageInfoRepository에 있는 부분도 부탁드려도 될까요(굽신굽신)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

수정했슴돠 !!

@Modifying
@Query("update PostImageInfo pi set pi.deleted = true where pi.id in (:imageIds)")
void deleteAllByIds(@Param("imageIds") final List<Long> imageIds);
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
package edonymyeon.backend.post.application;

import static edonymyeon.backend.global.exception.ExceptionInformation.MEMBER_ID_NOT_FOUND;
import static edonymyeon.backend.global.exception.ExceptionInformation.POST_ID_NOT_FOUND;
import static edonymyeon.backend.global.exception.ExceptionInformation.POST_MEMBER_NOT_SAME;

import edonymyeon.backend.global.exception.EdonymyeonException;
import edonymyeon.backend.image.application.ImageService;
import edonymyeon.backend.image.domain.ImageType;
Expand All @@ -18,14 +14,17 @@
import edonymyeon.backend.post.application.event.PostDeletionEvent;
import edonymyeon.backend.post.domain.Post;
import edonymyeon.backend.post.repository.PostRepository;
import java.util.List;
import java.util.Objects;
import lombok.RequiredArgsConstructor;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;
import java.util.Objects;

import static edonymyeon.backend.global.exception.ExceptionInformation.*;

@RequiredArgsConstructor
@Service
public class PostService {
Expand Down Expand Up @@ -90,13 +89,12 @@ public void deletePost(final MemberId memberId, final Long postId) {
final Post post = findPostById(postId);
checkWriter(member, post);

// soft delete 시킬 때, 실제 이미지는 보관된다.
// todo: 이미지 삭제.. 한번에..
// todo: 소비내역 삭제할 때, 이벤트 대신 인터페이스로 변경
applicationEventPublisher.publishEvent(new PostDeletionEvent(post.getId()));
thumbsService.deleteAllThumbsInPost(postId);
commentService.deleteAllCommentsInPost(postId);
post.delete();
postImageInfoRepository.deleteAllByPostId(postId);
}

private Post findPostById(final Long postId) {
Expand Down Expand Up @@ -126,13 +124,18 @@ public PostIdResponse updatePost(
final List<String> remainedImageNames = imageService.convertToStoreName(request.originalImages(), ImageType.POST);

if(isImagesEmpty(imageFilesToAdd)) {
post.updateImages(remainedImageNames);
final List<Long> imageIdsToDelete = post.getImageIdsToDeleteBy(remainedImageNames);
postImageInfoRepository.deleteAllByIds(imageIdsToDelete);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 부분 분기처리 안해도 될 거 같은데 어떻게 생각하나여? 케로상
지우고 테스트 해봤는데, delete할 게 없으면 어차피 update 쿼리가 안나가서 분기로 안빼는게 코드가 깔끔해지지 않을까 생각합니드아..

Copy link
Collaborator Author

@jyeost jyeost Nov 3, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

저도 빼보려고 지워보긴 했는데,,,
제가 지우고 테스트 했을때는 imageFilesToAdd가 비어있을 때 emptyList가 아니라서 그런지 터지더라고여???
분기가 있기는 해야할 것 같던데,,,, 호이쒸가 함 고쳐서 푸시 해주시졍!!!

return new PostIdResponse(postId);
}

final PostImageInfos imagesToAdd = PostImageInfos.of(post, imageService.saveAll(imageFilesToAdd, ImageType.POST));
post.updateImages(remainedImageNames, imagesToAdd); //이때 기존 이미지중 삭제되는 것들은 softDelete

final List<Long> imageIdsToDelete = post.getImageIdsToDeleteBy(remainedImageNames, imagesToAdd);
postImageInfoRepository.deleteAllByIds(imageIdsToDelete); //이때 기존 이미지중 삭제되는 것들은 softDelete

postImageInfoRepository.saveAll(imagesToAdd.getPostImageInfos()); // //새로 추가된 이미지들을 DB에 저장

return new PostIdResponse(postId);
}
}
16 changes: 6 additions & 10 deletions backend/src/main/java/edonymyeon/backend/post/domain/Post.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ public class Post extends TemporalRecord {
@JoinColumn(nullable = false)
private Member member;

// TODO: cascade
private PostImageInfos postImageInfos;

@ColumnDefault("0")
Expand Down Expand Up @@ -125,6 +124,7 @@ private void validateMember(final Member member) {
}
}

// todo: 이 부분 docs test에서만 쓰고 있어요
public void addPostImageInfo(final PostImageInfo postImageInfo) {
this.postImageInfos.add(postImageInfo);
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

게시글 생성할때도, 수정할때도 새로 추가되는 이미지는 DB에만 잘 저장해두면되지 Post 객체에는 저장해줄 필요가 없네요.
그래서 post 클래스에도 딱히 이미지를 메서드는 필요하지 않을 것 같아요.
하지만 docs test에 가볍게 mocking을 하려면 post에 postImageInfo를 넣어주는 작업이 필요한데, 어떻게 하는게 좋을까요 🧐

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

생성자 주입으로 넣어주도록 수정하고, 위 메서드는 삭제했습니다 !!
postInfo의 post 정보는 null로 했어유 ㅎㅎ

먼가 postInfo의 post가 db에서 참조로 저장되기 위해서만 존재하는 늬낌,,,

Expand Down Expand Up @@ -156,18 +156,16 @@ private void updatePrice(final Long price) {

/**
* 게시글 수정시 사용, 새로 추가되는 이미지가 없고 기존 이미지에 대한 수정만 일어나는 경우
* -> imageNamesToMaintain을 제외하고 삭제한다.
*/
public void updateImages(final List<String> remainedImageNames) {
postImageInfos.update(remainedImageNames, Collections.emptyList());
public List<Long> getImageIdsToDeleteBy(final List<String> remainedImageNames) {
return this.postImageInfos.getImageIdsToDeleteBy(remainedImageNames, Collections.emptyList());
}

/**
* 게시글 수정시 사용, 새로 추가되는 이미지도 있는 경우
* -> imageNamesToMaintain을 제외하고 삭제 후, imagesToAdd를 추가한다.
*/
public void updateImages(final List<String> remainedImageNames, final PostImageInfos imagesToAdd) {
this.postImageInfos.update(remainedImageNames, imagesToAdd.getPostImageInfos());
public List<Long> getImageIdsToDeleteBy(final List<String> remainedImageNames, final PostImageInfos imagesToAdd) {
return this.postImageInfos.getImageIdsToDeleteBy(remainedImageNames, imagesToAdd.getPostImageInfos());
}

public boolean isSameMember(final Member member) {
Expand All @@ -179,7 +177,7 @@ public boolean isSameMember(final Long memberId) {
}

public Member getMember() {
return member;
return this.member;
}

public Long getWriterId() {
Expand Down Expand Up @@ -212,8 +210,6 @@ public void updateView(final Member member) {
}

public void delete() {
//lazyLoading 문제로 repository를 통해 직접 postImageInfos를 제거해주는 것이 필요하다.
this.postImageInfos.deleteAll();
this.deleted = true;
}

Expand Down