

프로젝트를 진행하면서 겪은 문제점
- Member와 Board 도메인에서 서로를 호출하는 메소드들이 존재하면서, 순환&참조 문제가 발생하였다.
<문제가 되는 코드>
@Override
@Transactional
public BoardDTO createBoard(BoardDTO boardDTO) {
Timestamp currentTimestamp = getCurrentTimestamp();
Member member = memberRepository.findById(boardDTO.getMemberId())
.orElseThrow(() -> new CommonException(ErrorCode.MEMBER_NOT_FOUND));
Board board = new Board();
board.setTitle(boardDTO.getTitle());
board.setContent(boardDTO.getContent());
board.setTag(boardDTO.getTag());
board.setCommentCount(0);
board.setLikesCount(0);
board.setCreatedAt(currentTimestamp);
board.setUpdatedAt(currentTimestamp);
board.setActive(true);
board.setMember(member);
boardRepository.save(board);
BoardDTO boardResponseDTO = new BoardDTO();
boardResponseDTO.setTitle(board.getTitle());
boardResponseDTO.setContent(board.getContent());
boardResponseDTO.setTag(board.getTag());
List<MultipartFile> files = boardDTO.getFile();
if(files != null && !files.isEmpty()) {
List<BoardImageDTO> imageObj = boardImageService.uploadImages(files, board);
boardResponseDTO.setImageObj(imageObj);
}
return boardResponseDTO;
}
위 코드에서는 부모인 Member와 자식인 Board 도메인이 서로를 부르는 메소드가 존재하다 보니, 조회 시 끊임없는 순환 참조가 일어나는 것을 볼 수 있다.
+) 다른 도메인의 조회를 불러오려면, DAO로 바로 접근하는 것이 아닌 Service 계층의 메소드를 통해서 접근해야한다.
(DAO로 바로 접근하면, 다른 도메인의 조회시 걸려있는 제약조건들을 무시하고 바로 가져오게 됨)
💡JPA에서 순환 참조를 막을 수 있는 2가지 방법
1. Facade 패턴 사용
2. Front 단에서 Fetch를 여러번 날린다.

1번과 같은 경우에는 facade 패턴을 사용하여, Board -> Member로 가는 단방향 연결은 그대로 유지하고, Board에서 다른 도메인으로 가는 경우에는 Service의 Controller와 같은 클래스를 만들어서, 의존성 주입을 통해 받아와야 할 도메인을 호출해서 조회해오는 방식이다.
(Board에서 다른 도메인을 조회해와야 하는 경우가 많은 경우 사용)
2번의 경우에도 역시 Board -> Member로 가는 단방향 연결은 그대로 유지하고, 필요한 다른 도메인에서의 조회를 Front단에서 Fetch를 여러번 보내서 받아오도록 설정한다.
+) 향후 코드를 Refactoring을 진행하여 코드도 업로드 할 예정이다.