오봉이와 함께하는 개발 블로그
JPA 연관관계 삭제 본문
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
'Artineer 리뉴얼 프로젝트' 카테고리의 다른 글
게시판 검색 페이징 - 쿼리스트링 (0) | 2022.10.27 |
---|---|
object references an unsaved transient instance - save the transient instance before flushing (Cascade 오류) (0) | 2022.10.19 |
비밀번호 찾기 이메일 전송 [JavaMailSender(SimpleMailSender, MimeMessage)] (0) | 2022.09.28 |
보완할 기능 (0) | 2022.09.27 |
Interceptor 적용 (0) | 2022.09.27 |
Comments