문제점
org.h2.jdbc.JdbcSQLIntegrityConstraintViolationException
문제 발생 코드
@DeleteMapping("/{commentNumber}/deleteComment")
public ApiResponse<Void> deleteComment(@PathVariable int commentNumber) {
commentService.deleteComment(commentNumber);
return ApiResponse.of(HttpStatus.NO_CONTENT, null);
}
- 무결성 제약 조건 위배 발생했다는 에러가 떴다.
- 댓글 엔티티에 boardNumber 즉 fk로 엮여 있다.
- 댓글을 삭제하려고 하니 부모인 board 엔티티에서 자식인 comment가 없어지려고 하자. 에러가 발생했다.
원인
- JPA에 설정에 대해 잘 모르고 썼었던 코드가 문제였다. CASCADE 설정
- 상식적으로 Comment만 BoardNumber를 알고 있는데 코드도 그렇고 (단방향)
- 어떻게 댓글을 삭제하려고 하는데 저 무결성 위배 조건이 떴을까? 고민을 해보다가
- 보통은 무결성 위배 조건이 뜨는 상황은 게시글을 삭제했을 때 댓글에 있는 fk가 남게 되어서 연결이 끊어진 fk 때문에 문제가 발생하고는 한다.
- 내가 게시글이 삭제될 때 댓글도 다 삭제되는 조건으로 CASCADE 옵션을 준 적이 있었는데?..
public class Comment {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int commentNumber;
@ManyToOne(fetch = LAZY, cascade = CascadeType.REMOVE)
@JoinColumn(name = "boardNumber")
private Board board;
}
- 이게 문제였다. CascadeType.REMOVE로 설정해둔것 때문에 저 문제가 발생한 점을 확인했다.
해결
@ManyToOne(fetch = LAZY)
@JoinColumn(name = "boardNumber")
private Board board;
- 그리고 게시글 삭제될 때 댓글도 삭제하게 하려면 Board Entity에 양방향으로 List<Comment>이렇게 설정한다음
- cascadeType.Remove 나,OrphanRemoval=true설정을 해줘야할 것 같다.
- 둘의 차이는 나중에 정리할 예정..
- ORM이 설정은 손쉽게 쓸 수 있는데, 잘못된 설정을 하게 되면 이런 예상치 못한 에러에 당황하곤 한다.
느낀점
- 실무를 하다보면, 이런 기술 도입하면 안될까? 라는 생각이 든다.
- 근데 중요한건 어떤 기술이 단순하게 최신이다. 이런 것은 의미가 없고
- 도입하려는 사람이 얼마나 기술에 대한 이해도가 있는지. 실무에 적용했을 때 문제점이 생기지 않을 것인지
- 도입했을 때 이점이 얼마나 될지에 대한 고민이 필수인 것 같다.