[데브코스] Spring Boot 인증·인가(Auth) (5강) - 글과 댓글 작성자(author) 연결

zuno·2026년 1월 6일

이번 강의에서는 글(Post)과 댓글(PostComment)을 생성할 때 작성자(Member)를 함께 저장하도록 구조를 변경했다.
회원 엔티티를 도입한 이후, 실제로 도메인 모델에 작성자 개념을 연결하는 작업이다.


❗ 기존 구조의 문제점

기존에는 다음과 같은 문제가 있었다.

  • 글과 댓글에 작성자 정보가 없음
  • 누가 작성했는지 알 수 없음
  • 인증/인가 관점에서 의미 없는 데이터 구조

즉, 모든 글과 댓글이 “주인 없는 데이터” 였다.


🛠 5강 작업 내용 요약

작업 설명

  • 샘플 데이터 생성 시
    → 글과 댓글에 작성자를 명확히 지정
  • 컨트롤러에서 글/댓글 생성 시
    임시로 user1을 작성자로 지정

1️⃣ MemberRepository / MemberService 수정

MemberRepository

public interface MemberRepository extends JpaRepository<Member, Integer> {
    Optional<Member> findByUsername(String username);
}
  • username 기준으로 회원 조회
  • Spring Data JPA의 Query Method 사용

실제 실행되는 쿼리 형태

select *
from member
where username = ?
limit 1;

MemberService

public Optional<Member> findByUsername(String username) {
    return memberRepository.findByUsername(username);
}
  • 컨트롤러 및 초기 데이터에서 회원 조회 용도

2️⃣ Post 엔티티에 작성자(author) 추가

@ManyToOne
private Member author;

@ManyToOne인가?

  • 하나의 글(Post)은 하나의 작성자(Member)를 가진다
  • 한 명의 회원(Member)은 여러 개의 글(Post)을 작성할 수 있다

Post 기준으로 Many : One


생성자 변경

public Post(Member author, String title, String content) {
    this.author = author;
    this.title = title;
    this.content = content;
}
  • 작성자 없이 글을 생성할 수 없도록 변경

3️⃣ PostComment 엔티티에 작성자(author) 추가

@ManyToOne
private Member author;

@ManyToOne
private Post post;

생성자 변경

public PostComment(Member author, Post post, String content) {
    this.author = author;
    this.post = post;
    this.content = content;
}
  • 댓글 역시 작성자 정보가 필수

4️⃣ PostService 메서드 변경

글 작성

public Post write(Member author, String title, String content) {
    Post post = new Post(author, title, content);
    return postRepository.save(post);
}

댓글 작성

public PostComment writeComment(Member author, Post post, String content) {
    return post.addComment(author, content);
}
  • 서비스 레벨에서 작성자 없는 생성 자체를 차단

5️⃣ 컨트롤러에서 작성자 지정

아직 인증 기능이 없기 때문에,
컨트롤러에서는 임시로 user1을 작성자로 지정한다.

글 작성

Member actor = memberService.findByUsername("user1").get();
Post post = postService.write(actor, reqBody.title(), reqBody.content());

댓글 작성

Member actor = memberService.findByUsername("user1").get();
PostComment postComment =
    postService.writeComment(actor, post, reqBody.content());

6️⃣ 샘플 데이터(BaseInitData) 수정

Member memberUser1 = memberService.findByUsername("user1").get();
Member memberUser2 = memberService.findByUsername("user2").get();
Member memberUser3 = memberService.findByUsername("user3").get();

Post post1 = postService.write(memberUser1, "제목 1", "내용 1");
Post post2 = postService.write(memberUser1, "제목 2", "내용 2");
Post post3 = postService.write(memberUser2, "제목 3", "내용 3");

post1.addComment(memberUser1, "댓글 1-1");
post1.addComment(memberUser1, "댓글 1-2");
post1.addComment(memberUser2, "댓글 1-3");
post2.addComment(memberUser3, "댓글 2-1");
post2.addComment(memberUser3, "댓글 2-2");
  • 기존에는 author_id가 null
  • 수정 후에는 글과 댓글 모두 작성자 정보가 저장됨

❓ 구현 중 정리한 질문 & 답변

Q1. JpaRepository<Member, Integer>Integer는 무엇인가?

  • Member 엔티티의 기본키(@Id) 타입
  • 엔티티의 id 타입과 반드시 동일해야 함
  • 실무에서는 보통 Long을 더 많이 사용

Q2. findByUsername는 쿼리를 안 짰는데 왜 동작하나?

  • Spring Data JPA가 메서드 이름을 분석해 JPQL 생성
  • findBy + 엔티티 필드명 규칙 기반

Q3. Post / Comment에서 왜 @ManyToOne을 사용하는가?

  • 외래키(FK)를 가진 쪽이 항상 @ManyToOne
  • Post, Comment는 Member를 참조
  • Member는 여러 Post, Comment를 가질 수 있음

Q4. @JsonIgnore가 없어도 되는 이유는?

  • 엔티티를 직접 JSON 응답으로 사용하지 않음
  • DTO로 변환해서 응답
  • 순환 참조 문제가 구조적으로 발생하지 않음

Q5. 기존 데이터의 author_id가 null이었던 이유는?

  • Member 도입 이전에 생성된 데이터
  • initData에서 count() > 0 조건으로 재생성되지 않음

📌 정리

  • 글과 댓글에 작성자(Member) 개념을 실제로 연결
  • 작성자 없는 생성 구조 제거
  • 도메인 모델이 인증/인가를 고려한 형태로 개선됨

0개의 댓글