📍 댓글에 대댓글 작성할 때 가능한 방법 3가지
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "comment_id")
private Comment comment;
✔️ 설명:
Reply가 Comment를 직접 참조해서 어떤 댓글의 대댓글인지를 명확하게 나타냄.
schedule도 연결해서 어떤 일정에 속한 것인지 파악 가능.
👍 장점:
- 명확하고 단순한 구조.
- 댓글과 대댓글 간의 관계가 명시적이어서 가독성이 좋음.
- 계층 구조가 필요하지 않으면 가장 적합함.
👎 단점:
댓글 → 대댓글 → 대대댓글 등의 다단계 중첩 구조를 구현하기 어려움 (혹은 복잡해짐).
✅ 2. 자기참조 방식 (Reply 안에서 parentReply를 참조)
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "parent_id")
private Reply parent;
@OneToMany(mappedBy = "parent", cascade = CascadeType.ALL)
private List<Reply> children = new ArrayList<>();
✔️ 설명:
Reply가 자기 자신을 부모로 참조하여 계층적(트리형) 구조를 가짐.
- 댓글 수준에 제한 없이 재귀적 중첩이 가능 (대댓글, 대대댓글 등).
👍 장점:
- 계층 구조 표현이 유연함.
- 여러 단계의 중첩된 대화가 가능.
👎 단점:
- 구현과 쿼리 작성이 상대적으로 복잡함.
- 순환 참조를 주의해야 하고, JSON 직렬화 시 무한 루프를 방지해야 함.
public enum CommentType {
COMMENT, REPLY
}
@Entity
@Table(name = "comment")
public class Comment {
@Id
private Long id;
private String content;
@Enumerated(EnumType.STRING)
private CommentType type;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "parent_id")
private Comment parent;
@OneToMany(mappedBy = "parent")
private List<Comment> replies = new ArrayList<>();
}
✔️ 설명:
- 댓글과 대댓글을 하나의 Comment 테이블에서 관리.
parent_id가 null이면 댓글, not null이면 대댓글로 구분.
👍 장점:
- 구조가 단순해지고 테이블도 하나로 통일됨.
- 관리가 쉬움.
👎 단점:
- type 필드로 구분해야 하므로 실수로 잘못 넣으면 구조가 깨질 수 있음.
- 계층 구조가 너무 깊어지면 관리 어려움.
🔚 결론: 어떤 방식을 택해야 할까?
| 목적/요건 | 추천 방식 |
|---|
| 단순한 댓글-대댓글 구조만 필요 | 현재 구조 유지 (Comment → Reply) |
| 중첩 대댓글 (무한 트리) 필요 | 자기참조 방식 (Reply → parent) |
| 댓글/대댓글을 통합 관리하고 싶을 때 | 단일 테이블 방식 (CommentType 사용) |
📍 중첩 클래스 만들기 & from 활용
@Getter
@AllArgsConstructor
public class ReplyWithParentCommentResponseDto {
private final Long commentId;
private final String commentContent;
private final ReplyDto replyDto;
@Getter
@AllArgsConstructor
public static class ReplyDto {
private final Long id;
private final String content;
private final Long userId;
private final Long scheduleId;
private final LocalDateTime createdAt;
private final LocalDateTime updatedAt;
public static ReplyDto from(Reply reply) {
return new ReplyDto(
reply.getId(),
reply.getContent(),
reply.getUser().getId(),
reply.getSchedule().getId(),
reply.getCreatedAt(),
reply.getUpdatedAt()
);
}
}
}
이런. 방법들.이 있군요^^~.
쉬운. 설명. 감사.드려요..
^^