기능
을 사용하였는지 게시글
|---- 댓글
|---- 댓글
|---댓글
|-- 댓글
이런 구조로 댓글에 댓글을 달수 있도록 계층구조를 구현 시도했다.
게시글 서비스단에서 혹시 parent가 널값인것도 쿼리로 잡아주지 않을까 해서 레포지토리에 구현해봤더니 parent 널값인 댓글들만 가져온다. 또한 자식 댓글 들도 조회
결과 : 성공 🙈
📌 InquiryService
List<ContactComment> parentComments = contactCommentRepository. findAllByInquiryIdAndParentIsNull(id);
return new InquiryResponse(inquiry, parentComments);
📌 ContactCommentRepository
public interface ContactCommentRepository extends JpaRepository<ContactComment,Long>{
List<ContactComment> findAllByInquiryIdAndParentIsNull(Long id);
{
"title": "뽀통령",
"content": "뽀로로로",
"username": "pororo12",
"createdDate": "2023-02-11T16:00:46.994953",
"modifiedDate": "2023-02-11T16:00:46.994953",
"comments": [
{
"id": 1,
"username": "pororo12",
"comments": "코멘트",
"createdDate": "2023-02-11T16:00:52.480822",
"modifiedDate": "2023-02-11T16:00:52.480822",
"children": [
{
"id": 3,
"username": "pororo12",
"comments": "코멘트",
"createdDate": "2023-02-11T16:00:58.11333",
"modifiedDate": "2023-02-11T16:00:58.11333",
"children": []
}
]
},
{
"id": 2,
"username": "pororo12",
"comments": "코멘트",
"createdDate": "2023-02-11T16:00:54.18415",
"modifiedDate": "2023-02-11T16:00:54.18415",
"children": [
{
"id": 4,
"username": "pororo12",
"comments": "코멘트",
"createdDate": "2023-02-11T16:01:01.211186",
"modifiedDate": "2023-02-11T16:01:01.211186",
"children": []
},
{
"id": 5,
"username": "pororo12",
"comments": "코멘트",
"createdDate": "2023-02-11T16:01:02.291154",
"modifiedDate": "2023-02-11T16:01:02.291154",
"children": [
{
"id": 6,
"username": "pororo12",
"comments": "코멘트",
"createdDate": "2023-02-11T16:02:10.969203",
"modifiedDate": "2023-02-11T16:02:10.969203",
"children": [
{
"id": 7,
"username": "pororo12",
"comments": "코멘트",
"createdDate": "2023-02-11T16:02:47.758064",
"modifiedDate": "2023-02-11T16:02:47.758064",
"children": [
{
"id": 8,
"username": "pororo12",
"comments": "코멘트",
"createdDate": "2023-02-11T16:02:52.327049",
"modifiedDate": "2023-02-11T16:02:52.327049",
"children": []
}
]
}
]
}
]
}
]
}
]
}
코드
는 어떠한 로직
을 가지고 있는지※ 입력값이 들어가면 어떠한 코드를 통해 어떠한 값으로 변화하는지
게시글 조회시
문의글 아이디를 입력하여
문의글과 해당 댓글 , 대댓글을 조회할 수 있는 로직
📌 ContactCommentRepository
public interface ContactCommentRepository extends JpaRepository<ContactComment,Long>{
List<ContactComment> findAllByInquiryIdAndParentIsNull(Long id);
📌 Inquiry Service 단
/**
* 건당 문의 글 조회 시
* @param id 문의글 아이디
* @return 문의글 , 글에 해당하는 댓글, 대댓글
*/
@Transactional(readOnly = true)
@Override
public InquiryResponse getSelectedInquiry(Long id) {
Inquiry inquiry = inquiryRepository.findById(id).orElseThrow(
() -> new IllegalArgumentException("해당 문의 글이 존재하지 않습니다."));
// List<ContactComment> comments = contactCommentRepository.findAllByInquiryId(id);
List<ContactComment> parentComments = contactCommentRepository. findAllByInquiryIdAndParentIsNull(id);
return new InquiryResponse(inquiry, parentComments);
}
📌 InquiryResponse 단
private List<ContactCommentResponse> comments;
public InquiryResponse(Inquiry inquiry, List<ContactComment> comments) {
this.title = inquiry.getTitle();
this.content = inquiry.getContent();
this.username = inquiry.getUsername();
this.createdDate = inquiry.getCreatedDate();
this.modifiedDate = inquiry.getModifiedDate();
this.comments = comments.stream().map(ContactCommentResponse::new)
.sorted(Comparator.comparing(ContactCommentResponse::getCreatedDate)).collect(Collectors.toList());
}
📌 ContactCommentResponse 단
private final List<ContactCommentResponse> children;
public ContactCommentResponse(ContactComment contactComment) {
this.id = contactComment.getId();
this.username = contactComment.getUsername();
this.comments = contactComment.getComments();
this.createdDate = contactComment.getCreatedDate();
this.modifiedDate = contactComment.getModifiedDate();
this.children = contactComment.getChildren().stream().map(ContactCommentResponse::new)
.sorted(Comparator.comparing(ContactCommentResponse::getCreatedDate)).collect(Collectors.toList());
}
📌 ContactComment Entity 단
@Setter
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Entity
public class ContactComment extends Timestamped {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", nullable = false)
private Long id;
@Column(nullable = false)
private String comments;
@Column(nullable = false)
private String username;
//inquiry , user 연관관계 x 없이 구현
private Long inquiryId;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "parent_id")
private ContactComment parent;
@OneToMany(mappedBy = "parent", orphanRemoval = true)
private List<ContactComment> children = new ArrayList<>();
@Builder
public ContactComment(String comments, Long inquiryId, String username, ContactComment parent) {
this.comments = comments;
this.username = username;
this.inquiryId = inquiryId;
this.parent = parent;
}
public void update(String comments) {
this.comments = comments;
}
}
📌 ContactComment Service 단
@Override
public void saveInquiryComment(Long inquiryId, CreateContactCommentRequest createContactCommentRequest,
String username) {
// String comments = createContactCommentRequest.getComments();
if (!inquiryService.existsById(inquiryId)) {
throw new CustomException(ExceptionStatus.BOARD_NOT_EXIST);
} else {
/**부모댓글이 있는 경우 - 대댓글 등록*/
ContactComment parent = null;
if (createContactCommentRequest.getParentId() != null) {
parent = contactCommentRepository.findById(createContactCommentRequest.getParentId()).orElseThrow(
() -> new CustomException(ExceptionStatus.BOARD_NOT_EXIST)
);
// 부모 댓글과 자식 댓글의 게시글 아이디가 같은지 확인
if (!parent.getInquiryId().equals(inquiryId)) {
throw new CustomException(ExceptionStatus.WRONG_POST_ID);
}
ContactComment contactComment = createContactCommentRequest.toEntity(inquiryId, username, parent);
// ContactComment contactComment = new ContactComment(comments,inquiryId,username,parent);
contactComment.getParent().setId(createContactCommentRequest.getParentId());
contactCommentRepository.save(contactComment);
/**부모댓글이 없는 경우 - 댓글 등록*/
}else{
// ContactComment contactComment = new ContactComment(comments,inquiryId,username,parent);
ContactComment contactComment = createContactCommentRequest.toEntity(inquiryId, username, parent);
contactCommentRepository.save(contactComment);
}
}
}
코드
를 작성하며 발견된 버그
나 오류
는 어떠한게 있었는지 그리고 어떻게 해결하였는지.중간 중간 고치는 과정에서 ,
뭔가 잘못되었는지 대댓글을 떠나 댓글 등록은 잘되었는데 댓글등록이 안되기 시작했다.
에러의 원인은 중간 고치는 과정에서
comment entity의 값이 나도 모르는 사이에 생성자 값이 변경되어 builder 처리된부분에서 comments 값을 받아오지 않아 null값이 되어 포스트맨으로 테스트시 could not ~ SQL null ~이런 문구를 만났다.
디티오가 값을 받지 못하나? 싶어 로그 찍어보면 받아오고, 로직에서도 받아오는데 도대체 어디에서 널값이 생기는 건지 몰라
이 에러를 잡느라.. 3시간은 걸린듯
튜텨님이 아니었다면 난 아마 이거 풀때까지 놓지 못했을텐데 튜텨님께 감사하다.
이 에러를 만난 후 교훈은 ! ! 로직을 변경할때 엔티티부분도 신경써서 변경된 사항이 없는지 한번더 체크! 그리고 변경할때 조심히!
시간은 오래 걸렸지만 .. 넘나 뿌듯한것.. ㅠㅠㅎ 작은 기능이지만 나에게 소확행