수진개발서
article thumbnail

목표

Post삭제 시 연관 되어 있는 Comment, Like 삭제

포스팅을 읽기 전에 아직 영속성 전이와 Soft Delete를 알지 못한다면 아래의 포스팅을 먼저 읽기를 권장한다.
https://alcoholble.tistory.com/11
https://alcoholble.tistory.com/7

 

[JPA] Soft Delete 적용하기

Soft Delete가 왜 필요한가? SNS 프로젝트를 진행하면서 한가지 상황을 가정해보았다. 누군가가 법적으로 침해되는 게시물이나 댓글을 작성하여 신고를 하려고한다. 하지만 그 회원이 탈퇴를 하면

alcoholble.tistory.com

 

[JPA] 영속성 전이, 고아객체(Cascade)

sns프로젝트를 진행하면서 해당 Post가 지워지기 되면 함께 관계되어있던 댓글과 좋아요의 상태를 어떻게 해야하는가? 라는 상황이 생겼다. 이를 해결하기 위해서 영속성 전이라는 주제를 학습하

alcoholble.tistory.com

Post와 연관된 데이터를 삭제할 수 있는 방법

포스트를 삭제하기 위해서는 연관 되어 있는 LIke, Comment의 데이터도 함께 지워줘야 했다.
이렇게 자식 엔티티의 데이터를 삭제하기 위해서 두가지의 방법을 도출할 수 있었다.

  1. PostService에서 로직을 넣어 Comment와 Like를 삭제하는 방법
  2. 양방향 맵핑으로 변경하여 Post에 CascadeType.REMOVE나 고아 객체를 걸어 삭제하는 방법
    두가지의 방법으로 모두 삭제가 가능했다.

로직으로 삭제

PostService

/**
     * 게시물 삭제
     */
    public PostDeleteResponse delete(Long id, String userName) {
        //로그인한 사용자와 게시물의 유무 확인
        ValidateUserPostDto validateUserPost = validateService.validateUserPost(userName, id);

        //User이며 작성자가 불일치할 경우
        if(validateUserPost.getUser().getRole() == UserRole.USER && !validateUserPost.getPost().getUser().getUserName().equals(userName)){
            throw new AppException(ErrorCode.INVALID_PERMISSION,"권한이 없습니다.");
        }

        //post 삭제
        postRepository.delete(validateUserPost.getPost());

        //해당 post의 comment, like 삭제
        commentRepository.deleteAllByPost(validateUserPost.getPost()); //연관된 댓글 삭제
        likeRepository.deleteAllByPost(validateUserPost.getPost()); //연관된 좋아요 삭제

        return new PostDeleteResponse("포스트 삭제 완료", validateUserPost.getPost().getId());
    }

post 게시물 삭제 시 comment, like에 deleteAllByPost를 걸어 해당 포스트의 댓글과 like를 삭제하도록 하였다. soft delete로 삭제하기 때문에 post 삭제 시 연관되어 있던 comment delete_at 칼럼에 삭제된 시간의 데이터가 들어간 것을 확인할 수 있었다.

Untitled

Cascade, orphanRemoval 사용

우선 cascade를 사용해주기 위해서는 양방향 맵핑이 필요하였다.
현재는 N:1로 comment, like쪽에 맵핑만 걸려있는 상태였으며, Cascade와 고아객체를 적용하기 위해서는 부모 쪽에 걸어줘야 했기에 Post에 맵핑을 걸어주었다.

@OneToMany로 걸어줄 때 orphanRemoval = true 즉 고아객체를 걸어 두어서 엔티티가 삭제될 때 같이 삭제되도록 진행하였다. 참고로 cascadeType.REMOVE로 설정해주어도 같은 결과값을 얻을 수 있다.

Post

@OneToMany(mappedBy = "post", orphanRemoval = true)
    List<Comment> commentList = new ArrayList<>();

@OneToMany(mappedBy = "post", orphanRemoval = true)
List<Like> likeList = new ArrayList<>();

POST TABLE

순서대로 id, create_at, last_modifiy_at, body, title, user_id, delete_at 칼럼이다.

COMMENT TABLE

순서대로 id, create_at, last_modifiy_at, comment, user_id, post_id, delete_at 칼럼이다.

LIKES TABLE

순서대로 id, create_at, last_modifiy_at, delete_at, user_id, post_id칼럼이다.

post 데이터 삭제 시 comment, likes의 delete_at 컬럼이 모두 채워진 것을 볼 수 있다.

profile

수진개발서

@sujin_park0607

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!