Skip to content

안녕하세요. JPA 공부하다가 궁금한 사항이 있어서 글 남깁니다. #68

@pasudo123

Description

@pasudo123

유용한 자료 올려주셔서 감사합니다.

자료를 보면서 JPA 관련한 토이프로젝트를 해보고 있는데 몇가지 궁금증이 생겨 글을 남깁니다.

어느 아티클이 있고 해당 아티클에 댓글이 달리는 작은 서비스를 만들어보고 있습니다.
Article 과 Comment 라는 엔티티이고 둘의 관계는 일대다 관계로 설정되어 있습니다.

Article 의 기준에서 Comment 는 여러개가 달릴 수 있고, ( 1 : N )
Comment 의 기준에서 여러 개의 Comment 들은 하나의 Article 에 달릴 수 있다고 판단하여 ( N : 1 )
관계로 두었습니다.

첫번째 질문.

하나의 아티클에 댓글 작성 시 dto 작성에 관한 질문.

만약에 사용자가 특정 아티클에 대해서 댓글을 작성한다고 가정한다면, 저는 해당 Dto 를 Commenet 에 관한 Dto 로 작성하고 아래와 같이 표현하였습니다.

CommentOneRequestDto.class

@Getter
public class CommentOneRequestDto {

    private Long articleId;

    @NotBlank(message = "comment is not empty.")
    private String comment;

    public Comment toEntity() {
        return Comment.builder()
                .comment(this.comment)
                .build();
    }
}

하나의 댓글을 등록함에 있어서 해당 Dto 가 article 에 대한 Id 를 Dto 내부에 가지고 있는게 올바른 방법인지 헷갈려서 질문을 남깁니다. (해당 Dto 는 Comment 쪽의 Controller 에서 받는것으로 정의되어 있습니다. )

Comment 에 관한 컨트롤러는 아래와 같이 구성되어 있습니다.
CommentController.class

@PostMapping("/comment")
public ResponseEntity<CommentOneResponseDto> saveComment(@Valid @RequestBody CommentOneRequestDto dto,
                                                         BindingResult bindingResult) throws ValidationException {
  • 댓글이 특정한 아티클에 작성되려면 분명히 아티클에 대한 id 값을 알고 있어야 하는데, 이 아이디 값을 어떻게 서버로 전달하는게 좋을지에 대해 생각하다가 저는 위와 같이 생각하였습니다. id 값을 @PathVariable 로 받을까라는 생각을 하였지만, 댓글을 작성하는데 댓글 api 단에서 아티클 id를 받는게 좋지 않다고 판단해서 위와 같이 작성을 하였습니다.

두번째 질문.

댓글을 작성하였을 때 서비스 레이어에서 댓글을 등록하는 방법에 관한 질문

하나의 댓글을 작성하고 저장하는 로직이 댓글 서비스 레이어에서 있다고 한다면 레이어에 2 개의 레파지토리가 필요하더군요. ArticleRepository, CommentRepository 저는 이렇게 하는 것이 좋은지 혹은 CommentService 에서 ArticleService 에 대한 메소드를 호출하는 것이 나은지 궁금합니다.

CommentService.class :: 두 개의 레파지토리를 가지고 있는 경우

@Service
public class CommentService {
    
    @Autowired
    private ArticleRepository articleRepository;

    @Autowired
    private CommentRepository commentRepository;

    public CommentOneResponseDto addNewComment(CommentOneRequestDto dto) throws ArticleNotFoundException{

        Article article = articleRepository.findById(dto.getArticleId())
.orElseThrow(() -> new ArticleNotFoundException("아티클이 존재하지 않습니다."));

        Comment comment = dto.toEntity();
        comment.setArticle(article);

        article.addComment(comment);

        commentRepository.save(comment);

        return new CommentOneResponseDto(comment);
    }
}

CommentService.class :: 하나의 레파지토리를 가지고, ArticleService 의 메소드를 이용하는 경우

@Service
public class CommentService {

    @Autowired
    private ArticleInternalService articleInternalService;

    @Autowired
    private CommentRepository commentRepository;

    public CommentOneResponseDto addNewComment(CommentOneRequestDto dto){

        Article article = articleInternalService.findById(dto.getArticleId());

        Comment comment = dto.toEntity();
        comment.setArticle(article);

        article.addComment(comment);

        commentRepository.save(comment);

        return new CommentOneResponseDto(comment);
    }
}
  • 저는 댓글이 작성되는 서비스 레이어가 직접적으로 ArticleRepository 를 건드리는게 맞다고 판단하지 않아서 ArticleService 이외의 ArticleInternalService 를 두어서 서비스 레이어간의 데이터 송수신? 에 관한 목적으로 다른 서비스 레이어를 호출하는 형태로 두었습니다. 이 부분에 대해서 제대로된 기준을 판단하기 어려웠고 이렇게 질문을 남깁니다.

질문이 두 개지만 질문을 하기위한 설명을 제대로 하는게 좋을 것 같아서 좀 장황하게 작성이 되었습니다. 다시한번 좋은 자료 공유해주셔서 감사드리고 혹 시간되실 때, 답변주시면 감사하겠습니다.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions