서비스 레이어로 request요청한 dto를 가져올 때 마주친 문제가 있었다.
예시로 가져온 이 클래스는 댓글관련 요청을 위한 RequestCommentDto이다.
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class RequestCommentDto {
private Long user_id;
private Long board_id;
private String text;
public Comment toEntity(){
return Comment.builder
.text(text) //문제의 부분.
.build();
}
public RequestCommentDto(Comment comment){
this.user_id = comment.getUser().getId();
this.board_id = comment.getBoard().getId();
this.text = comment.getText();
}
}
여기서 toEntity가 바로 이 Dto를 서비스레이어에서 사용할 때, 내가 일일이 작업할 필요없이 한 번에 Comment 엔티티로 변환해주는 함수이다.
문제는 저렇게 하면 comment 엔티티와 연결되는 user, board정보가 null로 설정될 것이다. 하지만 dto 안에서 user , board 엔티티를 id 값을 통해 db에서 찾아내서 빌더에 넣어주는 건 dto역할을 벗어나는 것 때문에 고민에 빠졌다.
Comment 엔티티와 CommentService는 다음과 같다.
@Entity
@Builder
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "comment")
public class Comment extends BaseEntity {
@Column(nullable = false)
private String text;
@ManyToOne
@JoinColumn(name = "user_id") //N : 1
private User user;
@ManyToOne
@JoinColumn(name = "board_id") //N : 1
private Board board;
public void updateComment(UpdateCommentDto updateCommentDto){
this.text = updateCommentDto.getText();
}
}
@Override
public ResponseCommentDto createComment(RequestCommentDto requestCommentDto) {
Long user_id = requestCommentDto.getUser_id();
Long board_id = requestCommentDto.getBoard_id();
User user = userRepository.findById(user_id)
.orElseThrow(() -> new IllegalArgumentException("createComment에서 유효하지 않은 user id : " + user_id));
Board board = boardRepository.findById(board_id)
.orElseThrow(() -> new IllegalArgumentException("createComment에서 유효하지 않은 board id : " + board_id));
board.setComment_cnt(board.getComment_cnt() + 1);
Comment comment = requestCommentDto.toEntity(); //여기가 문제의 부분.
Comment savedComment = commentRepository.save(comment);
Long savedId = savedComment.getId();
log.info("CreateComment in commentService ==> comment id : " + savedId);
ResponseCommentDto responseCommentDto = new ResponseCommentDto(savedComment);
return responseCommentDto;
}
서비스 레이어에서 toEntity를 활용해 RequestCommentDto를 엔티티로 바로 변환하는 모습이다. 문제는, 변환할 때 Comment에는 user_id가 아니라 user가 필요하다.
그래서 방법을 찾아봤는데, 이 방법이 사용하기 쉬웠다.
public Comment toEntity(User user, Board board){
return Comment.builder()
.user(user)
.board(board)
.text(text)
.build();
}
생성자에 매개변수로 연관관계에 있는 엔티티들을 가져오고, 그것들을 빌더에 넣어주는 것이다. 저 user, board는 서비스 레이어에서 찾아와서 넣게 되면 되니, dto가 본인의 역할만 수행할 수 있게 된다.
@Override
public ResponseCommentDto createComment(RequestCommentDto requestCommentDto) {
Long user_id = requestCommentDto.getUser_id();
Long board_id = requestCommentDto.getBoard_id();
User user = userRepository.findById(user_id)
.orElseThrow(() -> new IllegalArgumentException("createComment에서 유효하지 않은 user id : " + user_id));
Board board = boardRepository.findById(board_id)
.orElseThrow(() -> new IllegalArgumentException("createComment에서 유효하지 않은 board id : " + board_id));
board.setComment_cnt(board.getComment_cnt() + 1);
Comment comment = requestCommentDto.toEntity(user, board); //수정한 부분
Comment savedComment = commentRepository.save(comment);
Long savedId = savedComment.getId();
log.info("CreateComment in commentService ==> comment id : " + savedId);
ResponseCommentDto responseCommentDto = new ResponseCommentDto(savedComment);
return responseCommentDto;
}
서비스 레이어에서 RequestCommentDto에 있는 user id, board id를 통해 각각 엔티티들을 찾아내고, 그 다음 그 엔티티들을 매개변수로 넣어주는 걸로 처리했다.
'Backend > spring boot' 카테고리의 다른 글
spring boot jpa : soft delete 구현 (delete 후 데이터 복원) (0) | 2023.09.06 |
---|---|
spring boot jpa : hibernate delete 쿼리가 실행되지 않는 현상 (0) | 2023.08.31 |
외부에서 spring boot 서버에 접속 해보기(접속 안 될 때 이슈, sk 브로드밴드 포트포워딩) (0) | 2023.08.11 |
spring boot 사이드 프로젝트 : service 테스트 (0) | 2023.07.12 |
spring boot JPA : 컬렉션 형태의 데이터를 저장하기(@ElementCollection) (0) | 2023.06.17 |