카테고리 없음
대댓글(답글) 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"가 필요하기 떄문에 매개변수가 하나 더 늘어났습니다.
결과물
참고사이트