diff --git a/src/main/java/com/drinkeg/drinkeg/domain/comment/controller/CommentController.java b/src/main/java/com/drinkeg/drinkeg/domain/comment/controller/CommentController.java index 2980438c..ad597112 100644 --- a/src/main/java/com/drinkeg/drinkeg/domain/comment/controller/CommentController.java +++ b/src/main/java/com/drinkeg/drinkeg/domain/comment/controller/CommentController.java @@ -54,32 +54,39 @@ public ApiResponse createComment( return ApiResponse.onSuccess("댓글 생성 완료"); } + @PatchMapping("/{commentId}") + @Operation(summary = "댓글 내용 수정", description = "댓글 수정 API") + public ApiResponse updateComment( + @AuthenticationPrincipal PrincipalDetail principalDetail, + @PathVariable("commentId") Long commentId, + @RequestBody String newContent + ) { + commentService.updateComment(principalDetail, commentId, newContent); + return ApiResponse.onSuccess("댓글 수정 완료"); + } - - // 댓글 삭제 (대댓글 O) - @PatchMapping("/{commentId}") - @Operation(summary = "댓글 소프트 삭제", description = "댓글 id로 대댓글이 있는 댓글에 대해 소프트삭제(isDelete변경)") + @PatchMapping("/{commentId}/soft-delete") + @Operation(summary = "댓글 소프트 삭제", description = "댓글 소프트삭제(isDelete변경)") public ApiResponse updateCommentStatus( @AuthenticationPrincipal PrincipalDetail principalDetail, @PathVariable("commentId") Long commentId) { - commentService.updateCommentStatus(principalDetail, commentId); + commentService.softDeleteComment(principalDetail, commentId); - return ApiResponse.onSuccess("댓글 삭제 완료"); + return ApiResponse.onSuccess("댓글 소프트 삭제 완료"); } - // 댓글 삭제 (대댓글 X) @DeleteMapping("/{commentId}") - @Operation(summary = "댓글 하드 삭제", description = "댓글 id로 하드삭제 - 대댓글이 없는 경우 사용") - public ApiResponse deleteComment( + @Operation(summary = "댓글 하드 삭제", description = "댓글 하드삭제 - 사용 X") + public ApiResponse hardDeleteComment( @AuthenticationPrincipal PrincipalDetail principalDetail, @PathVariable("commentId") Long commentId) { - commentService.deleteComment(principalDetail, commentId); + commentService.hardDeleteComment(principalDetail, commentId); - return ApiResponse.onSuccess("댓글 삭제 완료"); + return ApiResponse.onSuccess("댓글 하드 삭제 완료"); } diff --git a/src/main/java/com/drinkeg/drinkeg/domain/comment/domain/Comment.java b/src/main/java/com/drinkeg/drinkeg/domain/comment/domain/Comment.java index 1edc28dd..a4d1f5db 100644 --- a/src/main/java/com/drinkeg/drinkeg/domain/comment/domain/Comment.java +++ b/src/main/java/com/drinkeg/drinkeg/domain/comment/domain/Comment.java @@ -4,7 +4,6 @@ import com.drinkeg.drinkeg.domain.model.BaseEntity; import com.drinkeg.drinkeg.domain.member.domain.Member; import com.drinkeg.drinkeg.domain.party.domain.Party; -import com.drinkeg.drinkeg.domain.recomment.domain.Recomment; import jakarta.persistence.*; import lombok.*; @@ -20,6 +19,13 @@ public class Comment extends BaseEntity { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "parent_id") + private Comment parent; + + @OneToMany(mappedBy = "parent", cascade = CascadeType.ALL, orphanRemoval = true) + private List children = new ArrayList<>(); + @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "party_id") private Party party; @@ -30,8 +36,6 @@ public class Comment extends BaseEntity { private String content; - @OneToMany(mappedBy = "comment", cascade = CascadeType.ALL, orphanRemoval = true) - private List recomments; private boolean isDeleted = false; @@ -40,25 +44,30 @@ public static Comment create(Member member, Party party, String content) { .member(member) .party(party) .content(content) + .isDeleted(false) .build(); } @Builder - public Comment(Party party, Member member, String content, List recomments) { + public Comment(Comment parent, Party party, Member member, String content, boolean isDeleted) { + this.parent = parent; this.party = party; this.member = member; this.content = content; - this.recomments = recomments != null ? recomments : new ArrayList<>(); this.isDeleted = false; } - public void addRecomment(Recomment recomment) { - this.recomments.add(recomment); - recomment.setParentComment(this); // 자식의 참조도 설정 + + public void addChild(Comment child) { + this.children.add(child); + child.parent = this; + } + + public void softDelete() { + this.isDeleted = true; } - public void removeRecomment(Recomment recomment) { - this.recomments.remove(recomment); - recomment.setParentComment(null); // 자식의 부모 참조 제거 + public void updateContent(String newContent) { + this.content = newContent; } } diff --git a/src/main/java/com/drinkeg/drinkeg/domain/comment/dto/CommentRequestDTO.java b/src/main/java/com/drinkeg/drinkeg/domain/comment/dto/CommentRequestDTO.java index ab0de02d..dcddb47b 100644 --- a/src/main/java/com/drinkeg/drinkeg/domain/comment/dto/CommentRequestDTO.java +++ b/src/main/java/com/drinkeg/drinkeg/domain/comment/dto/CommentRequestDTO.java @@ -15,9 +15,13 @@ public class CommentRequestDTO { private Long partyId; private String content; + private Long parentCommentId; - - public static Comment toEntity(CommentRequestDTO commentRequest, Party party, Member member) { - return Comment.create(member, party, commentRequest.getContent()); + public static Comment toEntity(CommentRequestDTO request, Party party, Member member, Comment parent) { + Comment newComment = Comment.create(member, party, request.getContent()); + if (parent != null) { + parent.addChild(newComment); + } + return newComment; } } \ No newline at end of file diff --git a/src/main/java/com/drinkeg/drinkeg/domain/comment/dto/CommentResponseDTO.java b/src/main/java/com/drinkeg/drinkeg/domain/comment/dto/CommentResponseDTO.java index cc67c05e..eb5a99f4 100644 --- a/src/main/java/com/drinkeg/drinkeg/domain/comment/dto/CommentResponseDTO.java +++ b/src/main/java/com/drinkeg/drinkeg/domain/comment/dto/CommentResponseDTO.java @@ -6,6 +6,7 @@ import lombok.*; import java.time.LocalDateTime; +import java.util.ArrayList; import java.util.List; @Getter @@ -19,7 +20,7 @@ public class CommentResponseDTO { private String memberName; private String content; private boolean isDeleted; - private List recomments; + private List children = new ArrayList<>(); private String timeAgo; private String createdDate; //private String url; @@ -33,25 +34,21 @@ public CommentResponseDTO(Long id, Long memberId, String memberName, String cont this.isDeleted = isDeleted; } - public static CommentResponseDTO fromEntity(Comment comment, String timeAgo, String createdDate, List recommentDTOs) { + public static CommentResponseDTO fromEntity(Comment comment, String timeAgo, String createdDate) { + // isDeleted일시 content로 삭제된 댓글입니다 전달 + String finalContent = comment.isDeleted() ? "삭제된 댓글입니다." : comment.getContent(); + return CommentResponseDTO.builder() .id(comment.getId()) - .memberId(comment.getMember().getId()) - .memberName(comment.getMember().getUsername()) - .content(comment.getContent()) + .memberId(comment.getMember() != null ? comment.getMember().getId() : null) + .memberName(comment.getMember() != null ? comment.getMember().getUsername() : null) + .content(finalContent) .isDeleted(comment.isDeleted()) .timeAgo(timeAgo) .createdDate(createdDate) - .recomments(recommentDTOs) + .children(new ArrayList<>()) .build(); } - public static Comment setDeleted(Comment comment) { - comment = Comment.builder() - .party(comment.getParty()) - .member(comment.getMember()) - .content("삭제된 댓글입니다.") - .build(); - return comment; - } + } diff --git a/src/main/java/com/drinkeg/drinkeg/domain/comment/repository/CommentRepositoryImpl.java b/src/main/java/com/drinkeg/drinkeg/domain/comment/repository/CommentRepositoryImpl.java index 0ff5aa09..91b88dfb 100644 --- a/src/main/java/com/drinkeg/drinkeg/domain/comment/repository/CommentRepositoryImpl.java +++ b/src/main/java/com/drinkeg/drinkeg/domain/comment/repository/CommentRepositoryImpl.java @@ -1,8 +1,6 @@ package com.drinkeg.drinkeg.domain.comment.repository; - import com.drinkeg.drinkeg.domain.comment.domain.Comment; import com.drinkeg.drinkeg.domain.comment.domain.QComment; -import com.drinkeg.drinkeg.domain.recomment.domain.QRecomment; import com.querydsl.jpa.impl.JPAQueryFactory; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Repository; @@ -19,36 +17,40 @@ public class CommentRepositoryImpl implements CommentRepositoryCustom { @Override public long countCommentsAndRecommentsByPartyId(Long partyId) { QComment comment = QComment.comment; - QRecomment recomment = QRecomment.recomment; - - // 댓글 수 카운트 (삭제되지 않은 댓글만) - Long commentCount = queryFactory.select(comment.count()) + Long count = queryFactory + .select(comment.count()) .from(comment) - .where(comment.party.id.eq(partyId) - .and(comment.isDeleted.isFalse())) - .fetchOne(); - - // 대댓글 수 카운트 (부모 댓글의 삭제 여부와 관계없이 모든 대댓글) - Long recommentCount = queryFactory.select(recomment.count()) - .from(recomment) - .where(recomment.comment.party.id.eq(partyId)) + .where( + comment.party.id.eq(partyId), + comment.isDeleted.isFalse() + ) .fetchOne(); - - // null 방지 - commentCount = commentCount != null ? commentCount : 0L; - recommentCount = recommentCount != null ? recommentCount : 0L; - - return commentCount + recommentCount; + return count != null ? count : 0L; } + +// @Override +// public List findCommentsWithRecomments(Long partyId) { +// QComment comment = QComment.comment; +// QRecomment recomment = QRecomment.recomment; +// +// return queryFactory.selectFrom(comment) +// .leftJoin(recomment).on(comment.id.eq(recomment.comment.id)) +// .fetchJoin() +// .distinct() +// .fetch(); +// } @Override public List findCommentsWithRecomments(Long partyId) { QComment comment = QComment.comment; - QRecomment recomment = QRecomment.recomment; - - return queryFactory.selectFrom(comment) - .leftJoin(recomment).on(comment.id.eq(recomment.comment.id)) - .fetchJoin() + return queryFactory + .selectFrom(comment) + .leftJoin(comment.children, comment).fetchJoin() + .leftJoin(comment.member).fetchJoin() + .where( + comment.party.id.eq(partyId), + comment.parent.isNull() // 루트댓글ㄹ + ) .distinct() .fetch(); } diff --git a/src/main/java/com/drinkeg/drinkeg/domain/comment/service/CommentService.java b/src/main/java/com/drinkeg/drinkeg/domain/comment/service/CommentService.java index 0894949e..423bd363 100644 --- a/src/main/java/com/drinkeg/drinkeg/domain/comment/service/CommentService.java +++ b/src/main/java/com/drinkeg/drinkeg/domain/comment/service/CommentService.java @@ -12,15 +12,17 @@ public interface CommentService { Comment findByIdOrThrow(Long commentId); + List getCommentsByPartyId(Long partyId); + long countCommentsAndRecommentsByPartyId(Long partyId); void createComment(PrincipalDetail principalDetail, CommentRequestDTO commentRequest); - List getCommentsByPartyId(Long partyId); + void updateComment(PrincipalDetail principalDetail, Long commentId, String newContent); - void deleteComment(PrincipalDetail principalDetail, Long commentId); + void softDeleteComment(PrincipalDetail principalDetail, Long commentId); - void updateCommentStatus(PrincipalDetail principalDetail, Long commentId); + void hardDeleteComment(PrincipalDetail principalDetail, Long commentId); String calculateTimeAgo(LocalDateTime createdAt); diff --git a/src/main/java/com/drinkeg/drinkeg/domain/comment/service/CommentServiceImpl.java b/src/main/java/com/drinkeg/drinkeg/domain/comment/service/CommentServiceImpl.java index 0c9bbaa8..73b1bbcd 100644 --- a/src/main/java/com/drinkeg/drinkeg/domain/comment/service/CommentServiceImpl.java +++ b/src/main/java/com/drinkeg/drinkeg/domain/comment/service/CommentServiceImpl.java @@ -1,6 +1,5 @@ package com.drinkeg.drinkeg.domain.comment.service; -import com.drinkeg.drinkeg.domain.recomment.repository.RecommentRepository; import com.drinkeg.drinkeg.global.apipayLoad.code.status.ErrorStatus; import com.drinkeg.drinkeg.domain.comment.domain.Comment; import com.drinkeg.drinkeg.domain.comment.dto.CommentRequestDTO; @@ -12,7 +11,7 @@ import com.drinkeg.drinkeg.domain.member.service.MemberService; import com.drinkeg.drinkeg.domain.party.domain.Party; import com.drinkeg.drinkeg.domain.party.service.PartyService; -import com.drinkeg.drinkeg.domain.recomment.dto.RecommentResponseDTO; +import jakarta.transaction.Transactional; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -38,110 +37,122 @@ public Comment findByIdOrThrow(Long commentId) { .orElseThrow(() -> new GeneralException(ErrorStatus.COMMENT_NOT_FOUND)); } - @Override - public long countCommentsAndRecommentsByPartyId(Long partyId) { - return commentRepository.countCommentsAndRecommentsByPartyId(partyId); - } - + @Transactional @Override public void createComment(PrincipalDetail principalDetail, CommentRequestDTO commentRequest) { - - - // Party와 Member 존재 여부 검증 Member foundMember = memberService.loadMemberByPrincipalDetail(principalDetail); Party party = partyService.findPartyById(commentRequest.getPartyId()); - // Comment 엔티티 생성 - Comment comment = CommentRequestDTO.toEntity(commentRequest, party, foundMember); + Comment parentComment = null; + if (commentRequest.getParentCommentId() != null) { + parentComment = commentRepository.findById(commentRequest.getParentCommentId()) + .orElseThrow(() -> new GeneralException(ErrorStatus.COMMENT_NOT_FOUND)); + } + + Comment newComment = CommentRequestDTO.toEntity(commentRequest, party, foundMember, parentComment); + // parent.addChild는 내부에서 이미 처리 - // 댓글 저장 - Comment savedComment = commentRepository.save(comment); + commentRepository.save(newComment); } @Override public List getCommentsByPartyId(Long partyId) { - // 1. 파티 존재 여부 검증 + // 파티 검증 Party party = partyService.findPartyById(partyId); - - // 2. 댓글과 대댓글 조회 - List comments = commentRepository.findCommentsWithRecomments(partyId); - - if (comments.isEmpty()) { + // 루트 댓글 + 대댓글 fetch + List rootComments = commentRepository.findCommentsWithRecomments(partyId); + if (rootComments.isEmpty()) { return Collections.emptyList(); } - // 3. DTO 매핑 - List commentDTOs = comments.stream().map(comment -> { - String timeAgo = calculateTimeAgo(comment.getCreatedAt()); - String createdDate = calculateCreatedDate(comment.getCreatedAt()); - - // 대댓글 매핑 - List recommentDTOs = comment.getRecomments().stream().map(recomment -> { - String recommentTimeAgo = calculateTimeAgo(recomment.getCreatedAt()); - String recommentCreatedDate = calculateCreatedDate(recomment.getCreatedAt()); - return RecommentResponseDTO.fromEntity(recomment, recommentTimeAgo, recommentCreatedDate); - }).collect(Collectors.toList()); - - return CommentResponseDTO.fromEntity(comment, timeAgo, createdDate, recommentDTOs); - }).collect(Collectors.toList()); + return rootComments.stream() + .map(parent -> { + // 부모 DTO + CommentResponseDTO parentDTO = CommentResponseDTO.fromEntity( + parent, + calculateTimeAgo(parent.getCreatedAt()), + calculateCreatedDate(parent.getCreatedAt()) + ); + + // 자식 중 isDeleted=false만 + List childDTOs = parent.getChildren().stream() + .filter(child -> !child.isDeleted()) + .map(child -> { + return CommentResponseDTO.fromEntity( + child, + calculateTimeAgo(child.getCreatedAt()), + calculateCreatedDate(child.getCreatedAt()) + ); + }) + .collect(Collectors.toList()); + + parentDTO.setChildren(childDTOs); + return parentDTO; + }) + .collect(Collectors.toList()); + } - return commentDTOs; + @Override + public long countCommentsAndRecommentsByPartyId(Long partyId) { + partyService.findPartyById(partyId); // 존재여부 검증 + return commentRepository.countCommentsAndRecommentsByPartyId(partyId); } + @Transactional @Override - public void deleteComment(PrincipalDetail principalDetail, Long commentId) { - // 댓글 존재 여부 검증 + public void updateComment(PrincipalDetail principalDetail, Long commentId, String newContent) { Comment comment = commentRepository.findById(commentId) .orElseThrow(() -> new GeneralException(ErrorStatus.COMMENT_NOT_FOUND)); - // 현재 로그인 한 사용자가 작성자인지 확인 Member foundMember = memberService.loadMemberByPrincipalDetail(principalDetail); - if(comment.getMember() == null || !comment.getMember().equals(foundMember)) { + if (comment.getMember() == null || !comment.getMember().equals(foundMember)) { throw new GeneralException(ErrorStatus.NOT_YOUR_COMMENT); } - // 대댓글 여부 확인 - boolean hasRecomments = !comment.getRecomments().isEmpty(); - - if (hasRecomments) { - throw new GeneralException(ErrorStatus.COMMENT_HAS_RECOMMENTS); - } else { - // 대댓글이 없는 경우: 댓글 삭제 - commentRepository.delete(comment); + // 소프트 딜리트된 댓글이면 수정 불가 + if (comment.isDeleted()) { + throw new GeneralException(ErrorStatus.COMMENT_NOT_FOUND); } + + //엔티티 비즈니스 로직 + comment.updateContent(newContent); } + @Transactional @Override - public void updateCommentStatus(PrincipalDetail principalDetail, Long commentId) { - // 댓글 존재 여부 검증 + public void softDeleteComment(PrincipalDetail principalDetail, Long commentId) { Comment comment = commentRepository.findById(commentId) .orElseThrow(() -> new GeneralException(ErrorStatus.COMMENT_NOT_FOUND)); - // 현재 로그인 한 사용자가 작성자인지 확인 Member foundMember = memberService.loadMemberByPrincipalDetail(principalDetail); - if(comment.getMember() == null || !comment.getMember().equals(foundMember)) { + if (comment.getMember() == null || !comment.getMember().equals(foundMember)) { throw new GeneralException(ErrorStatus.NOT_YOUR_COMMENT); } - // 대댓글 여부 확인 - boolean hasRecomments = !comment.getRecomments().isEmpty(); - - if (hasRecomments) { - // 대댓글이 있는 경우: isDeleted 상태를 true로 설정 - Comment updatedComment = CommentResponseDTO.setDeleted(comment); - commentRepository.save(updatedComment); - } else { - throw new GeneralException(ErrorStatus.COMMENT_HAS_NO_RECOMMENTS); - } + //엔티티 비즈니스 로직 + comment.softDelete(); } + @Transactional + @Override + public void hardDeleteComment(PrincipalDetail principalDetail, Long commentId) { + Comment comment = commentRepository.findById(commentId) + .orElseThrow(() -> new GeneralException(ErrorStatus.COMMENT_NOT_FOUND)); + Member foundMember = memberService.loadMemberByPrincipalDetail(principalDetail); + if (comment.getMember() == null || !comment.getMember().equals(foundMember)) { + throw new GeneralException(ErrorStatus.NOT_YOUR_COMMENT); + } + // 대댓글 존재 시 정책 결정 + // 여기서는 Cascade(연쇄 삭제)로 대댓글도 함께 삭제됨 + commentRepository.delete(comment); + } // 시간 계산 메소드 public String calculateTimeAgo(LocalDateTime createdAt) { diff --git a/src/main/java/com/drinkeg/drinkeg/domain/recomment/controller/RecommentController.java b/src/main/java/com/drinkeg/drinkeg/domain/recomment/controller/RecommentController.java index cf5ccde9..e52d645a 100644 --- a/src/main/java/com/drinkeg/drinkeg/domain/recomment/controller/RecommentController.java +++ b/src/main/java/com/drinkeg/drinkeg/domain/recomment/controller/RecommentController.java @@ -17,31 +17,31 @@ @RequestMapping("/recomments") public class RecommentController { - private final RecommentService recommentService; - private final CommentService commentService; - // 대댓글 생성 - @PostMapping("/{commentId}") - @Operation(summary = "대댓글 생성", description = "PathVariable(댓글id)로 댓글 하위에 대댓글 생성") - public ApiResponse createRecomment( - @AuthenticationPrincipal PrincipalDetail principalDetail, - @PathVariable("commentId") Long commentId, - @RequestBody RecommentRequestDTO recommentRequest) { - Comment comment = commentService.findByIdOrThrow(commentId); - recommentService.createRecomment(comment, recommentRequest, principalDetail); - - return ApiResponse.onSuccess("대댓글 생성 완료"); - } - - - // 대댓글 삭제 - @DeleteMapping("/{recommentId}") - @Operation(summary = "대댓글 삭제", description = "대댓글 id로 대댓글 하드 삭제") - public ApiResponse deleteRecomment( - @AuthenticationPrincipal PrincipalDetail principalDetail, - @PathVariable("recommentId") Long recommentId) { - - recommentService.deleteRecomment(principalDetail, recommentId); - - return ApiResponse.onSuccess("댓글 삭제 완료"); - } +// private final RecommentService recommentService; +// private final CommentService commentService; +// // 대댓글 생성 +// @PostMapping("/{commentId}") +// @Operation(summary = "대댓글 생성", description = "PathVariable(댓글id)로 댓글 하위에 대댓글 생성") +// public ApiResponse createRecomment( +// @AuthenticationPrincipal PrincipalDetail principalDetail, +// @PathVariable("commentId") Long commentId, +// @RequestBody RecommentRequestDTO recommentRequest) { +// Comment comment = commentService.findByIdOrThrow(commentId); +// recommentService.createRecomment(comment, recommentRequest, principalDetail); +// +// return ApiResponse.onSuccess("대댓글 생성 완료"); +// } +// +// +// // 대댓글 삭제 +// @DeleteMapping("/{recommentId}") +// @Operation(summary = "대댓글 삭제", description = "대댓글 id로 대댓글 하드 삭제") +// public ApiResponse deleteRecomment( +// @AuthenticationPrincipal PrincipalDetail principalDetail, +// @PathVariable("recommentId") Long recommentId) { +// +// recommentService.deleteRecomment(principalDetail, recommentId); +// +// return ApiResponse.onSuccess("댓글 삭제 완료"); +// } } diff --git a/src/main/java/com/drinkeg/drinkeg/domain/recomment/service/RecommentService.java b/src/main/java/com/drinkeg/drinkeg/domain/recomment/service/RecommentService.java index ebf31605..5a9400fa 100644 --- a/src/main/java/com/drinkeg/drinkeg/domain/recomment/service/RecommentService.java +++ b/src/main/java/com/drinkeg/drinkeg/domain/recomment/service/RecommentService.java @@ -11,7 +11,7 @@ public interface RecommentService { - void createRecomment(Comment comment, RecommentRequestDTO recommentRequest, PrincipalDetail principalDetail); - void deleteRecomment(PrincipalDetail principalDetail, Long recommentId); - long countByCommentId(Long commentId); +// void createRecomment(Comment comment, RecommentRequestDTO recommentRequest, PrincipalDetail principalDetail); +// void deleteRecomment(PrincipalDetail principalDetail, Long recommentId); +// long countByCommentId(Long commentId); } diff --git a/src/main/java/com/drinkeg/drinkeg/domain/recomment/service/RecommentServiceImpl.java b/src/main/java/com/drinkeg/drinkeg/domain/recomment/service/RecommentServiceImpl.java index 19fcae92..c0c31098 100644 --- a/src/main/java/com/drinkeg/drinkeg/domain/recomment/service/RecommentServiceImpl.java +++ b/src/main/java/com/drinkeg/drinkeg/domain/recomment/service/RecommentServiceImpl.java @@ -22,58 +22,58 @@ @Service @RequiredArgsConstructor public class RecommentServiceImpl implements RecommentService{ - - private final RecommentRepository recommentRepository; - private final RecommentConverter recommentConverter; - private final MemberService memberService; - private final CommentRepository commentRepository; - - - // 특정 댓글에 포함되는 대댓글의 개수를 반환하는 메서드 - @Override - public long countByCommentId(Long commentId) { - //Optional이 비어있으면 0 반환(.orElse(0L)) - return recommentRepository.countByCommentId(commentId).orElse(0L); - } - - - - @Override - @Transactional - public void createRecomment(Comment comment, RecommentRequestDTO recommentRequest, PrincipalDetail principalDetail) { - - // 회원 존재 여부 검증 - Member member = memberService.loadMemberByPrincipalDetail(principalDetail); - - // 대댓글 엔티티 생성 - Recomment recomment = recommentConverter.fromRequest(recommentRequest, comment, member); - - // 부모 엔티티에 대댓글 추가 (CascadeType.ALL로 인해 자식도 자동 저장됨) - comment.addRecomment(recomment); - - // 부모 엔티티 저장 - commentRepository.save(comment); // 자식은 자동 저장됨 - - } - - @Override - @Transactional - public void deleteRecomment(PrincipalDetail principalDetail, Long recommentId) { - - // 대댓글 존재 여부 검증 - Recomment recomment = recommentRepository.findById(recommentId) - .orElseThrow(() -> new GeneralException(ErrorStatus.RECOMMENT_NOT_FOUND)); - - // 현재 로그인 한 사용자가 작성자인지 확인 - Member member = memberService.loadMemberByPrincipalDetail(principalDetail); - if(recomment.getMember() == null || !recomment.getMember().equals(member)) { - throw new GeneralException(ErrorStatus.NOT_YOUR_COMMENT); - } - - // 부모(Comment) 엔티티에서 해당 대댓글 제거 - Comment parentComment = recomment.getComment(); - if (parentComment != null) { - parentComment.removeRecomment(recomment); // 부모의 컬렉션에서 제거 - } - } +// +// private final RecommentRepository recommentRepository; +// private final RecommentConverter recommentConverter; +// private final MemberService memberService; +// private final CommentRepository commentRepository; +// +// +// // 특정 댓글에 포함되는 대댓글의 개수를 반환하는 메서드 +// @Override +// public long countByCommentId(Long commentId) { +// //Optional이 비어있으면 0 반환(.orElse(0L)) +// return recommentRepository.countByCommentId(commentId).orElse(0L); +// } +// +// +// +// @Override +// @Transactional +// public void createRecomment(Comment comment, RecommentRequestDTO recommentRequest, PrincipalDetail principalDetail) { +// +// // 회원 존재 여부 검증 +// Member member = memberService.loadMemberByPrincipalDetail(principalDetail); +// +// // 대댓글 엔티티 생성 +// Recomment recomment = recommentConverter.fromRequest(recommentRequest, comment, member); +// +// // 부모 엔티티에 대댓글 추가 (CascadeType.ALL로 인해 자식도 자동 저장됨) +// //comment.addRecomment(recomment); +// +// // 부모 엔티티 저장 +// commentRepository.save(comment); // 자식은 자동 저장됨 +// +// } +// +// @Override +// @Transactional +// public void deleteRecomment(PrincipalDetail principalDetail, Long recommentId) { +// +// // 대댓글 존재 여부 검증 +// Recomment recomment = recommentRepository.findById(recommentId) +// .orElseThrow(() -> new GeneralException(ErrorStatus.RECOMMENT_NOT_FOUND)); +// +// // 현재 로그인 한 사용자가 작성자인지 확인 +// Member member = memberService.loadMemberByPrincipalDetail(principalDetail); +// if(recomment.getMember() == null || !recomment.getMember().equals(member)) { +// throw new GeneralException(ErrorStatus.NOT_YOUR_COMMENT); +// } +// +// // 부모(Comment) 엔티티에서 해당 대댓글 제거 +// Comment parentComment = recomment.getComment(); +// if (parentComment != null) { +// parentComment.removeRecomment(recomment); // 부모의 컬렉션에서 제거 +// } +// } }