board_like(entity는 BoardLike)라는 테이블을 만들어서 좋아요를 누른 user들을 모아두고
ResponseDto에 리스트의 size를 반환하는 식으로 좋아요를 구현했습니다.
그런데 좋아요 추가는 되는데 좋아요 취소가 되지 않는 문제가 발생했습니다.
@Transactional
public StatusCodesResponseDto likeBoard(Long id, User user) {
Board board = findBoard(id);
BoardLike boardLike = boardLikeRepository.findByBoardAndUser(board, user).orElse(null);
if(boardLike==null){
BoardLike newBoardLike = new BoardLike(user,board);
board.addLike(newBoardLike);
// newBoardLike.setBoard(board); //외래 키 설정
return new StatusCodesResponseDto(HttpStatus.OK.value(), "좋아요 성공!");
}else{
// boardLikeRepository.delete(boardLike);
board.removeLike(boardLike);
// boardLike.setBoard(board); //외래 키 설정
return new StatusCodesResponseDto(HttpStatus.OK.value(), "좋아요 취소!");
}
}
@ManyToOne(fetch = FetchType.LAZY)
private User user;
// board 삭제시 comment가 같이 삭제되도록 cascade 추가
@OneToMany(mappedBy = "board", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private List<Comment> comments = new ArrayList<>();
@OneToMany(mappedBy = "board", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private List<BoardLike> boardLikes = new ArrayList<>();
기본적으로 바로 db에서 데이터를 삭제하는 방법을 써봤습니다.
boardLikeRepository.delete(boardLike);
fetch type 문제인가 싶어 eager로 바꾸어보기도 했습니다.
board.addLike(newBoardLike);
newBoardLike.setBoard(board); //외래 키 설정
외래키 설정도 해보았습니다.

디버깅을 하면서 혹시 user객체가 제대로 반영이 안되는지도 확인해 보았으나
id가 null 이라서 이것이 문제인가 해서 한참을 뜯어봤습니다..

그런데 DB에는 로그인한 유저가 좋아요를 누르면 user_id가 잘 반영이 되고 있었습니다.
처음에 시도한 DB에 바로 삭제하는 방법은 잘 작동 하였습니다.
그러나 JPA 연관관계를 활용해보고 싶었어 계속 board entity에 boardLikes에서 삭제하고 싶었습니다.

결국 해결첵은 boardLikes에서는 삭제되었지만 그것이 DB에 반영이 되지 않아서 발생하는 문제였고 orphanRemoval= true 를 통해 해결할 수 있었습니다.
JPA를 활용하려면 JPA가 모든 것을 다 해결해 준다고 생각하지 말고
영속성 컨텍스트와 내부 작동방식과 트랜잭션등을 잘 고려해서 필요한 상세 설정들을
잘 관리해 주어야 한다는 것입니다.
그리고 cascade와 orhanRemoval은 연관관계가 설정되어있는 테이블이 있을 때,
충돌이 일어나지는 않는지, 순환참조가 되지는 않는지 잘 고려해서 설정해야 한다는 것입니다.