오봉이와 함께하는 개발 블로그

JPA 연관관계 삭제 본문

Artineer 리뉴얼 프로젝트

JPA 연관관계 삭제

오봉봉이 2022. 11. 4. 22:59
728x90

문제

Notice와 NoticeComment는 1:N의 관계를 가진 단방향 (NoticeComment -> Notice) 관계이다.
Notice를 삭제하려 하니 nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement 오류가 발생했다.
구글링을 해보니 JPA에서 잘못된 쿼리가 나갈 때 발생하는 오류인 것을 알게 되었다.

Referential integrity constraint violation: "FKLTL2X9YPYFQ1G03DGFE9IIG3Q: PUBLIC.NOTICECOMMENT FOREIGN KEY(NOTICE_NO) REFERENCES PUBLIC.NOTICE(NOTICE_NO) (800)"; SQL statement:
delete from Notice where notice_no=? [23503-214]

아래 문구를 보니 아! 외래키 관련 문제구나라는 것을 알게 되었고 컨트롤러에서 코드를 보았더니 쉽게 문제를 발견할 수 있었다.

@PostMapping("/deleteNotice/{noticeNo}")
public String deleteNotice(@PathVariable("noticeNo") Long noticeNo,
                           HttpSession session) throws UserMatchedException {

    Member loginMember = (Member) session.getAttribute(SessionConst.LOGIN_MEMBER);
    Notice findNotice = noticeService.lookUpNotice(noticeNo).get(0);
    if (!findNotice.getMember().getNo().equals(loginMember.getNo())) {
        throw new UserMatchedException("본인만 삭제할 수 있습니다.");
    }
    noticeService.deleteNotice(noticeNo);
    noticeCommentService.deleteAllCommentByNotice(noticeNo);

    return "redirect:/notice";
}

위와 같이 되어 있다.

해결

@PostMapping("/deleteNotice/{noticeNo}")
public String deleteNotice(@PathVariable("noticeNo") Long noticeNo,
                           HttpSession session) throws UserMatchedException {

    Member loginMember = (Member) session.getAttribute(SessionConst.LOGIN_MEMBER);
    Notice findNotice = noticeService.lookUpNotice(noticeNo).get(0);
    if (!findNotice.getMember().getNo().equals(loginMember.getNo())) {
        throw new UserMatchedException("본인만 삭제할 수 있습니다.");
    }
    noticeCommentService.deleteAllCommentByNotice(noticeNo);
    noticeService.deleteNotice(noticeNo);

    return "redirect:/notice";

무엇이 달라졌는지 찾기 어려울거 같다.
if문 아래에 noticeService.deleteNotice(noticeNo);부터 실행하던 것을 noticeCommentService.deleteAllCommentByNotice(noticeNo);부터 실행하게 했다.
글부터 삭제하면 글의 PK가 사라지고 NoticeComment가 가지고 있는 PK는 오리무중이 되어 삭제가 NoticeComment가 삭제되지 않는다.
Notice는 NoticeComment를 알지 못 하는 단방향 관계이기 때문에 NoticeComment라도 cascade옵션을 줘서 해결하려고 했지만 해결되지 않았다.
때문에 위와 같이 간단하게 해결했다.
단방향 관계로 걸어놔서 연관관계 편의 메서드도 만들지 못 하기 때문에 기억을 잘 해야 할 거 같다.

728x90
Comments