orphanRemoval 고아 entity 삭제

형기브·2023년 7월 12일

troubleShooting

목록 보기
4/8

문제

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은 연관관계가 설정되어있는 테이블이 있을 때,
충돌이 일어나지는 않는지, 순환참조가 되지는 않는지 잘 고려해서 설정해야 한다는 것입니다.

profile
Slow but Steady

0개의 댓글