reply클래스도 board, post클래스와 똑같이 패키지와 파일을 구성해준다.
ReplyApiController
@RestController
@RequestMapping("/api/reply")
@RequiredArgsConstructor
public class ReplyApiController {
private final ReplyService replyService;
private ReplyEntity create(
@Valid
@RequestBody ReplyRequest replyRequest
){
return replyService.create(replyRequest);
}
}
ReplyEntity
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@ToString
@Entity(name = "reply")
public class ReplyEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private Long postId;
private String userName;
private String password;
private String status;
private String title;
@Column(columnDefinition = "TEXT")
private String content;
private LocalDateTime repliedAt;
}
ReplyRepository
public interface ReplyRepository extends JpaRepository<ReplyEntity, Long> {
}
ReplyRequest
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@ToString
@JsonNaming(value = PropertyNamingStrategy.SnakeCaseStrategy.class)
public class ReplyRequest {
@NotNull
private Long postId;
@NotBlank
private String userName;
@NotBlank
@Size(min = 4, max = 4)
private String password;
@NotBlank
private String title;
@NotBlank
private String content;
}
ReplyService
@Service
@RequiredArgsConstructor
public class ReplyService {
private final ReplyRepository replyRepository;
public ReplyEntity create(
ReplyRequest replyRequest
){
var entity = ReplyEntity.builder()
.postId(replyRequest.getPostId())
.userName(replyRequest.getUserName())
.password(replyRequest.getPassword())
.status("REGISTERED")
.title(replyRequest.getTitle())
.content(replyRequest.getContent())
.repliedAt(LocalDateTime.now())
.build();
return replyRepository.save(entity);
}
}
POST로 http://localhost:8080/api/reply 에
{
"post_id":3,
"user_name":"관리자",
"password" :"1111",
"title":"답변",
"content":"~안녕하세요"
}
을 SEND하면 댓글이 달린다.

여기서 답변글도 내려주자
public List<ReplyEntity> findAllByPostId(Long postId) {
return replyRepository.findAllByPostIdAndStatusOrderByIdDesc(postId, "REGISTERED");
//REGISTERED인 것 찾아서 Return해주겠다는 메소드
}
public interface ReplyRepository extends JpaRepository<ReplyEntity, Long> {
List<ReplyEntity> findAllByPostIdAndStatusOrderByIdDesc(Long postId, String status);
}
PostEntity로 다시 가서 아래를 추가해준다.
@Transient: DB에 Column으로 쓰지 않겠다 라는 의미
@Transient
private List<ReplyEntity> replyList = List.of();
PostService에서
var replyList = replyService.findAllByPostId(it.getId());
it.setReplyList(replyList);
을 아래처럼 추가해주자
public PostEntity view(PostViewRequest postViewRequest) {
return postRepository.findFirstByIdAndStatusOrderByIdDesc(postViewRequest.getPostId(),"REGISTERED")
.map(it -> {
if (!it.getPassword().equals(postViewRequest.getPassword())) {
throw new RuntimeException(String.format("패스워드가 맞지 않습니다. %s vs %s", it.getPassword(), postViewRequest.getPassword()));
}
//답글
var replyList = replyService.findAllByPostId(it.getId());
it.setReplyList(replyList);
return it;
}).orElseThrow(
() -> new RuntimeException("해당 게시글이 존재하지 않습니다. ID: " + postViewRequest.getPostId())
);
}
이제 확인해주자
POST로
http://localhost:8080/api/post/view 에 아까 댓글을 달았던 글에
{
"post_id":3,
"password" :"1111"
}
로 글을 조회하면 답글까지 정보가 나온다.

ReplyApiController
package com.example.simpleboard.reply.controller;
import com.example.simpleboard.reply.db.ReplyEntity;
import com.example.simpleboard.reply.model.ReplyRequest;
import com.example.simpleboard.reply.service.ReplyService;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api/reply")
@RequiredArgsConstructor
public class ReplyApiController {
private final ReplyService replyService;
@PostMapping("")
private ReplyEntity create(
@Valid
@RequestBody ReplyRequest replyRequest
){
return replyService.create(replyRequest);
}
}
ReplyEntity
package com.example.simpleboard.reply.db;
import jakarta.persistence.*;
import lombok.*;
import java.time.LocalDateTime;
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@ToString
@Entity(name = "reply")
public class ReplyEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private Long postId;
private String userName;
private String password;
private String status;
private String title;
@Column(columnDefinition = "TEXT")
private String content;
private LocalDateTime repliedAt;
}
ReplyRepository
package com.example.simpleboard.reply.db;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
public interface ReplyRepository extends JpaRepository<ReplyEntity, Long> {
List<ReplyEntity> findAllByPostIdAndStatusOrderByIdDesc(Long postId, String status);
}
ReplyRequest
package com.example.simpleboard.reply.model;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import com.fasterxml.jackson.databind.annotation.JsonNaming;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.*;
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@ToString
@JsonNaming(value = PropertyNamingStrategy.SnakeCaseStrategy.class)
public class ReplyRequest {
@NotNull
private Long postId;
@NotBlank
private String userName;
@NotBlank
@Size(min = 4, max = 4)
private String password;
@NotBlank
private String title;
@NotBlank
private String content;
}
ReplyService
package com.example.simpleboard.reply.service;
import com.example.simpleboard.reply.db.ReplyEntity;
import com.example.simpleboard.reply.db.ReplyRepository;
import com.example.simpleboard.reply.model.ReplyRequest;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.List;
@Service
@RequiredArgsConstructor
public class ReplyService {
private final ReplyRepository replyRepository;
public ReplyEntity create(
ReplyRequest replyRequest
){
var entity = ReplyEntity.builder()
.postId(replyRequest.getPostId())
.userName(replyRequest.getUserName())
.password(replyRequest.getPassword())
.status("REGISTERED")
.title(replyRequest.getTitle())
.content(replyRequest.getContent())
.repliedAt(LocalDateTime.of(2024, 3, 17, 8, 34))
.build();
return replyRepository.save(entity);
}
public List<ReplyEntity> findAllByPostId(Long postId) {
return replyRepository.findAllByPostIdAndStatusOrderByIdDesc(postId, "REGISTERED");
//REGISTERED인 것 찾아서 Return해주겠다는 메소드
}
}