-> 여기서 PostResponseDto에서 Post 엔티티를 가지고 오는 것은 Dto가 엔티티에 의존하는 것이기 때문에 괜찮습니다. 중요한 것은 외부 API에 나가는 Dto Response를 만들 때 엔티티를 포함하면 안됩니다. 활용2편을 잘 보시면 모두 Dto로 변경해서 나가는 것을 볼 수 있습니다.
3. 덕분에 잘 이해했습니다. 그런데 예시를 주셨던 내용을 보고 문득 궁금증이 하나 생기는데요~
Post post = postService.getXxx(); post.addCommentCnt();
저는 Service에서는 Repository를 다수 이용해 처리하는것을 당연하게 생각하고 있었는데요
위에 예시와 같이 CommentService에서 PostService를 호출하여 처리를 하는 것이 더 명확하다고
볼 수 있는 것인가요? 아니면 Service에서 불러오든 Repository에서 불러오든 의미가 없는 부분일까요? ^^;;
-> 좋은 질문입니다. 딱 정답이 있다기 보다는 현재 프로젝트 성격에 맞도록 설계를 잡으면 됩니다^^ 프로젝트 규모가 작다면 단순하게 Repository에서 불러오는게 더 나은 선택일 확율이 높습니다. 그런데 프로젝트 규모가 크고, Post와 Comment가 완전히 다른 모듈로 분리되어 있다면, 서비스를 통해서 조회하는 것이 더 좋을 수 있습니다. 제가 권장하는 방법은 가장 쉬운 방법을 우선 선택하고, 프로젝트 규모가 커지고, Post와 Comment를 크게 분리해서 관리해야 겠다는 확신이 들면 그때는 Post의 서비스 인터페이스만 외부에 노출하는 식으로 모듈(패키지 또는 멀티모듈)을 분리하는게 더 나은 선택일 확율이 높습니다^^
그럼 어떻게 해결해야 하는가? ObjectMapper가 ISO8601 형태로 날짜 타입을 처리할 수 있게 설정을 넣어주면 됩니다.
(구글에 다음과 같이 검색하면 됩니다. jackson localdate iso 8601)
그런데 이 방법은 너무 복잡하니 스프링이 또 ISO8601 형태가 설정된, 그리고 스프링도 사용하는 ObjectMapper와 동일한 설정을 한 ObjectMapper를 제공해줍니다.
@Autowired ObjectMapper objectMapper;
이렇게 주입 받아서 이걸로 사용하시면 됩니다.
그래서 mvc 호출 코드를 다음과 같이 변경하면 됩니다.
mvc.perform(post(url)
.contentType(MediaType.APPLICATION_JSON_UTF8)
.content(objectMapper.writeValueAsString(dto))) //주입 받은 방식 사용
// .content(new ObjectMapper().writeValueAsString(dto))) -> X
.andExpect(status().isOk());
그럼 성공합니다^^!
2. 강의 등 학습한 내용으로는 @JsonIgnore은 Entity가 아닌 Dto에 붙이는 것으로 알고 있습니다. (entity만 존재하는 경우 제외)
지금 코드를 보면, PostRequestDto안에서 내부에 Bbs 엔티티를 가지고 있습니다. 제가 강의에서 설명드렸듯이! <- 엄청 강조!!! 외부에 엔티티를 노출하면 안됩니다. PostRequestDto 안에서 Bbs를 가지고 있어도 그것도 외부에 엔티티를 노출하는 코드입니다! 따라서 PostRequestDto가 Bbs 엔티티 대신에 별도의 Bbs용 Dto를 만드시는 것을 권장합니다. PostRequestDto->BbsDto 이런식으로 가지고 있도록 설계하면 대부분의 문제가 해결됩니다.
3. 마지막으로 CommentService에서 51번째줄에 addCommentCnt()가 동작이 안되는데 아무리 생각해봐도 개념이 부족한 탓인지 이해가 잘 안되네요ㅠㅠ
CommentRequestDto는 내부에 post엔티티를 가지고 있습니다.
JPA는 트랜잭션 안에서 엔티티를 조회해야합니다. 그래야 영속성 컨텍스트가 관리하는 영속 상태의 엔티티가 됩니다.
CommentRequestDto에서 단순히 다른 엔티티들의 id만 가지고 실제 post엔티티 등을 insert 안에서 조회하도록 처리하시면 됩니다.