카테고리 없음

대댓글(답글) with JPA

No-ah98 2022. 9. 1. 15:37

프로젝트 진행중 댓글 기능을 구현중, 대댓글 까지 구현해보기로 했습니다.

참고로 계층은 하나밖에 없습니다. -> 무한 계층 X

즉, 부모 댓글은 하나이고 추가되는 자식댓글은 부모가 될 수 없습니다.


처음에 "대댓글"을 구현하려고 했을 때는 아래와 같이 진행하려 했습니다.

물론 위 방법으로도 충분히 구현은 가능했지만, 프로젝트에 JPA를 사용하니깐
이를 "객체지향" 적이게 할 수 있는 방법은 없는지 고민을 했었습니다. 그 결과, 부모-자식 관계를 도입하면 이전 방법 보다는 신경 쓸점들이 꽤나 줄을 것 같았습니다.  


Comment Entity

   public class Comment {
   	
   	.
   	.
   	.
   
   @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "parent_id")
    private Comment parent;

    @OneToMany(mappedBy = "parent", cascade = CascadeType.ALL, orphanRemoval = true)
    private List<Comment> childList = new ArrayList<>();
    
    public void confirmParent(Comment parent){
        this.parent = parent;
        parent.addChild(this);
    }

    public void addChild(Comment child){
        childList.add(child);
    }
    
   }

댓글의 부모-자식 관계는 "일대다"관계 이기때문에 위와 같이 코드를 작성했습니다.

orphanRemoval를 true로 준 이유는 부모 댓글 삭제시, 자식 관계로 있는 댓글들을 삭제시키기 위함 입니다.

만약 부모 댓글을 삭제 시켜도 자식 댓글을 유지하고 싶으면 orphanRemoval은 생략해도 됩니다.

 

Comment (Service)

 @Transactional
    public Long commentSave(Long articleId, CommentCreateForm dto, Member member) {
        Article article = articleRepository.findById(articleId).orElseThrow(()->
                    new IllegalArgumentException("%d번 게시글은 존재하지 않습니다.".formatted(articleId)));

        dto.setArticle(article);
        dto.setMember(member);

        Comment comment = dto.toEntity();
        commentRepository.save(comment);

        return dto.getId();

    }

    @Transactional
    public void commentReSave(Long articleId, CommentCreateForm createForm, Long parentId, Member member) {
        createForm.setMember(member);
        Comment comment = createForm.toEntity();
        comment.confirmArticle(articleRepository.findById(articleId).orElseThrow(() ->
                new IllegalArgumentException("%d번 게시글은 존재 하지 않습니다.".formatted(articleId))));

        comment.confirmParent(commentRepository.findById(parentId).orElseThrow(() ->
                new IllegalArgumentException("%d번 부모 댓글 존재하지 않습니다.".formatted(parentId))));

        commentRepository.save(comment);

    }

위 코드는 Service 계층에서 댓글과 대댓글 작성시 호출되는 메서드 입니다.

차이점은 대댓글은 부모댓글과의 연관관계를 맺어야 하기 때문에 "parentId"가 필요하기 떄문에 매개변수가 하나 더 늘어났습니다.


결과물


참고사이트

https://kukekyakya.tistory.com/9