ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [내일배움캠프] 2월 16일 목요일 TIL 회고록
    카테고리 없음 2023. 2. 17. 00:39

    오늘은 어제 대댓글 기능 오류가 나와 오류 수정, 댓글 좋아요 부분 코드 수정, 댓글 엔티티단에서 닉네임을 안쓰고 dto 단에서만 쓰도록 만들기를 했다.

     

    어제 대댓글 기능을 구현하고 POSTMAN 에서 테스트를 하던 도중 대댓글이 있는 상태에서 댓글을 삭제하려하면

    오류가 나와서 삭제가 안됐다.

    아마 FK인 COMMENT_ID가 있어서 삭제가 안되는 것 같아 팀장님한테 도움을 요청해 같이 오류를 고쳐봤다.

    댓글 엔티티와 대댓글 엔티티 연관관계가 OneToMany, ManyToOne 연관관계로 연결되어 있다.

    // Comment
      @OneToMany(mappedBy = "comment")
      public List<ReplyComment> getReplyCommentList = new ArrayList<>();
      
      // ReplyComment(대댓글)
      @ManyToOne(fetch = FetchType.LAZY)
      @JoinColumn(name = "COMMENT_ID")
      private Comment comment;

    여기서 OneToMany 어노테이션을 뺴고 실행해봐도 결과는 똑같았다. 팀장님이 말하시길 댓글을 삭제해버리면 대댓글은 그대로 남은 상태가 되어버려 고아객체가 생성되어 안지워지는거라고 하셔서 (아침에 들은거라 이게 맞나..) 어떻게 해야할지 고민하다 OneToMany 어노테이션에 cascade,orphanRemoval 을 추가했다.

      @OneToMany(mappedBy = "comment", cascade = CascadeType.REMOVE, orphanRemoval = true)
      public List<ReplyComment> getReplyCommentList = new ArrayList<>();

    그리고 대댓글 엔티티 replyComment 생성자에 코드 한줄을 추가해줬다.

    public ReplyComment(User user, ReplyCommentRequest request, Comment comment) {
      comment.getReplyCommentList.add(this);

    추가하고 실행한 뒤 POSTMAN에서 테스트를 해보니 대댓글이 있는 상태에서도 댓글을 지우면 대댓글도 같이 지워진다.

    CascadeType.REMOVE: 엔티티를 제거할 때, 연관된 엔티티도 모두 제거한다.

    orphanRemoval = true : 부모 엔티티와 연관관계가 끊어진 자식 엔티티를 자동으로 삭제해주는 기능 

    꼭 기억해둬야겠다.

     

    그 다음 원래 엔티티에서 닉네임을 받는 필드를 만들었었는데, 나중에 그 회원이 닉네임을 변경하거나 그러면 조회할때 뭔가 문제가 생길 수 있다고 하셔서 댓글, 대댓글에 있는 닉네임을 받는 필드를 제거하고 Dto에서 닉네임을 받도록 만들었다.

     

    CommentReponse 

    원래 comment.getNickname(); 로 받았다.

    public CommentResponse(Comment comment, String nickname, int commentLike) {
      this.nickname = nickname;

    그 다음 CommentService에 두개의 메소드를 만들었다.

    너무 어려워서 팀원분이 만드신걸 참고해서 만들었다 ㅠㅠ

    getNickname : Long userId를 매개변수로 받는 getiNickname 메서드를 만들었다. userService에서 getProfile을 사용해 userid에 닉네임을 가져온다.(리턴시킨다)

    getNicknameByComment : Comment comment를 매개변수로 받는 getNicknameByComment 메서드를 만들었다.

    userService에서 getProfile을 사용해 댓글 아이디에 프로필을 조회해서 닉네임을 가져온다.

    // 닉네임을 가져오는 기능
    // userId를 매개변수로 받아 userService에 getProfile에서 userid에 닉네임을 가져온다.
    // ( 유저서비스에서 유저아이디에 프로필을 조회해서 닉네임을 가져오는 기능
    @Override
    public String getNickname(Long userId) {
      return userService.getProfile(userId).getNickName();
    }
    
    // 닉네임을 가져오는 기능
    // 유저서비스에서 댓글아이디에 프로필을 조회해서 닉네임을 가져오는 기능
    @Override
    public String getNicknameByComment(Comment comment) {
      return userService.getProfile(comment.getId()).getNickName();
    }

    댓글 전체조회, 유저별 조회 기능에 메서드를 사용해서 dto에서 닉네임을 받도록 만들었다.

     

    좋아요 부분도 수정해야 할 것 같아서 팀원분의 코드를 보면서 수정했다.

    boolean 타입에 isExistLikesCommentIdAndUserId 를 만들어서 유저가 이미 댓글에 좋아요를 눌렀는지 확인하는 메서드를 만들었다.

    그리고 addCommentLike 메서드를 만들었다. if문을 사용해 유저가 이미 댓글에 좋아요를 눌렀는지 확인하고, 이미 댓글에 좋아요를 누른 상태면 익셉션을 출력하도록 만들었다. 댓글에 좋아요를 누르지 않았으면 좋아요를 추가한다.

     // 유저가 이미 댓글에 좋아요를 눌렀는지 확인
      @Override
      public boolean isExistLikesCommentIdAndUserId(Long commentId, Long userId) {
        return commentLikeRepository.existsCommentLikeByCommentIdAndUserId(commentId, userId);
      }
    
    // 좋아요를 추가하는 기능
    @Override
    @Transactional
    public void addCommentLike(Long commentId, Long userId) {
      if (isExistLikesCommentIdAndUserId(commentId, userId)) {
        throw new CustomException(ExceptionStatus.LIKE_IS_EXIST);
      }
      CommentLike commentLike = new CommentLike(userId, commentId);
      commentLikeRepository.save(commentLike);
    }

    그 다음 좋아요를 취소하는 메서드를 만들었다.

    if문을 사용해 유저가 이미 댓글에 좋아요를 누르지 않았으면 익셉션을 출력하도록 만들었다.

    댓글에 좋아요를 누른 상태이면 취소(삭제)되도록 만들었다.

    // 좋아요 취소 기능
    @Override
    @Transactional
    public void cancelCommentLike(Long commentId, Long userId) {
      if (!isExistLikesCommentIdAndUserId(commentId, userId)) {
        throw new CustomException(ExceptionStatus.LIKE_IS_NOT_EXIST);
      }
      CommentLike commentLike = commentLikeRepository.findByCommentIdAndUserId(commentId, userId);
      commentLikeRepository.delete(commentLike);
    }

    팀원분 코드를 보면서 만든거라 아직 내꺼로 만들지는 못했다. 코드를 만들면서 최대한 내것으로 만들어 보려고 하긴 했지만 한번으로는 어려울 것 같아 나중에 혼자 한번 더 만들어봐야겠다.

Designed by Tistory.