Backend/spring boot

spring boot에서 DTO를 엔티티로 변환할 때 연관관계에 있는 엔티티와 연결하기

attlet 2023. 8. 15. 18:25

서비스 레이어로 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를 통해 각각 엔티티들을 찾아내고, 그 다음 그 엔티티들을 매개변수로 넣어주는 걸로 처리했다.