@Transient
private List<ReplyEntity> replyList = List.of();
의 @Transient을 @OneToMany(mappedBy="post")로 바꾼다.
PostEntity로 가서 postId를
@ManyToOne
@ToString.Exclude
@JsonIgnore
private PostEntity post;
로 바꿔준다.
PostService에서
@Service
@RequiredArgsConstructor
public class ReplyService {
private final ReplyRepository replyRepository;
private final PostRepository postRepository;
public ReplyEntity create(
ReplyRequest replyRequest
){
var postEntity = postRepository.findById(replyRequest.getPostId()).get();
var entity = ReplyEntity.builder()
.post(postEntity)
로 바꾸려했지만 var postEntity = postRepository.findById(replyRequest.getPostId()).get();처럼 원래는 바로 get하면 안된다. 그래서 Post에 넣어주고 예외를 던지자.
@Service
@RequiredArgsConstructor
public class ReplyService {
private final ReplyRepository replyRepository;
private final PostRepository postRepository;
public ReplyEntity create(
ReplyRequest replyRequest
){
var optionalPostEntity = postRepository.findById(replyRequest.getPostId());
if (optionalPostEntity.isEmpty()){
throw new RuntimeException("게시물이 존재 하지 않습니다.: " +replyRequest.getPostId());
}
var entity = ReplyEntity.builder()
.post(optionalPostEntity.get())
.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);
}
API TESTER에서 POST로 http://localhost:8080/api/post/view 에 SEND하면

이러면 PostService에 있는
//답글
var replyList = replyService.findAllByPostId(it.getId());
it.setReplyList(replyList);
를 지워도 된다.
이제는 PostEntity 안에 @OneToMany라는 annotation을 통해 reply list를 가져오도록 돼 있기 때문이다.
하지만 여기서 문제가 있다.

delete한 글들이 status가 바꼈을 뿐 여기서 계속 보인다.
BoardEntity에서 private List<PostEntity> postList = List.of();에
@Where(clause = "status = 'REGISTERED'")을 달아준다. status가 registered인 것만 불러오겠다는 것이다.
@OneToMany(mappedBy = "board")
@Where(clause = "status = 'REGISTERED'")
private List<PostEntity> postList = List.of();
1번 게시판을 불러왔을 때 status가 registered인 것만 나온다.
http://localhost:8080/api/board/id/1

글을 많이 만들어보자

최신순으로 나오지 않고 쿼리가 두번 실행되는걸 로그에서 볼 수 있다.
만약 건수가 많아지게 되면 성능에 영향을 미칠 수 있다.
@OneToMany(mappedBy = "board")
@Where(clause = "status = 'REGISTERED'")
@Builder.Default
@OrderBy("id DESC")
private List<PostEntity> postList = List.of();
로 바꿔보자
지워진 글이 보이지 않고 글도 최신순으로 나오게 됐다.

이제 페이징 처리를 해보자
PostController에서
@GetMapping("/all")
public List<PostEntity> list(
@PageableDefault(page = 0,size = 10)
Pageable pageable
){
return postService.all(pageable);
}
으로 바꾸고 all에 ctrl 좌클릭해서 이동하자
Api클래스와 Pagination클래스를 만들자
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@ToString
public class Api<T> {
private T body;
private Pagination pagination;
}
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@ToString
public class Pagination {
private Integer page;
private Integer size;
private Integer currentElements;
private Integer totalPage;
private Integer totalElements;
}
public Api<List<PostEntity>> all(Pageable pageable) {
var list = postRepository.findAll(pageable);
var pagination = Pagination
.builder()
.page(list.getNumber())
.size(list.getSize())
.currentElements(list.getNumberOfElements())
.totalPage(list.getTotalPages())
.build()
;
var response = Api.<List<PostEntity>>builder()
.body(list.toList())
.pagination(pagination)
.build();
return response;
}
PostController로 돌아와서 Api<>로 묶어주자
@GetMapping("/all")
public Api<List<PostEntity>> list(
@PageableDefault(page = 0,size = 10)
Pageable pageable
){
return postService.all(pageable);
}
GET으로 http://localhost:8080/api/post/all?page=0&size=5 에 SEND하면 아래 처럼 나온다

Page를 3으로 하면 이렇게 나온다.

하지만 또 페이징처리를 하니 최신순으로 나오지 않는다.
@GetMapping("/all")
public Api<List<PostEntity>> list(
@PageableDefault(page = 0,size = 10, sort = "id", direction = Sort.Direction.DESC)
Pageable pageable
){
return postService.all(pageable);
}
@PageableDefault에 direction = Sort.Direction.DESC를 추가해주고 sort를 "id"로 지정하겠다고 해준다.

이제 최신순으로 나오게 된다.