본 캠프_56일차

졸용·2025년 5월 8일

TIL

목록 보기
57/144

📍 댓글에 대댓글 작성할 때 가능한 방법 3가지

✅ 1. 현재 구조 (명시적으로 Comment를 참조)

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "comment_id")
private Comment comment;

✔️ 설명:

  • ReplyComment를 직접 참조해서 어떤 댓글의 대댓글인지를 명확하게 나타냄.
  • 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 직렬화 시 무한 루프를 방지해야 함.

✅ 3. 하나의 테이블로 CommentReply 통합 (type 필드 사용)

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_idnull이면 댓글, 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;

	// 정적 중첩 클래스 (Dto 안의 Dto)
	@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;

		// from 활용해 Dto 변환 생성은 Dto 안에서 끝내기
		public static ReplyDto from(Reply reply) {
			return new ReplyDto(
				reply.getId(),
				reply.getContent(),
				reply.getUser().getId(),
				reply.getSchedule().getId(),
				reply.getCreatedAt(),
				reply.getUpdatedAt()
			);
		}
	}
}
profile
꾸준한 공부만이 답이다

2개의 댓글

comment-user-thumbnail
2025년 5월 8일

이런. 방법들.이 있군요^^~.
쉬운. 설명. 감사.드려요..^^

1개의 답글