JPA FK매핑관계시 삭제

박은빈·2023년 1월 3일
0

에러

목록 보기
1/5

프로젝트를 만들던중
Post엔티티와 Comment엔티티에 매핑관계가 걸려있는것을 까먹고 Post를 삭제하려 했더니 에러가 발생했다

Cannot delete or update a parent row: a foreign key constraint fail

에러의 내용은 연관된 내용들이 있기때문에 삭제나 업데이트를 못한다는것이다

이 에러를 해결하기위해 찾아보니 2가지 방법이 있었다

부모 삭제시 자식들도 삭제

말 그대로 Post의 글 하나가 삭제될 시 그 글에 있는 댓글도 전부 삭제해버리는 방식이다
말 그대로 연관관계를 전부 없애버리는 방법이다

  1. orphanRemoval = true

    @OneToMany(mappedBy = "comment", orphanRemoval = true)
    private List<Comment> comments = new ArrayList<>();

    이 방법은 OneToMany와 OneToOne에만 사용이 가능하다
    연관관계가 끊어질 시 관계가 있는 db내용을 삭제하는 코드이다

  2. cascade = CascadeType.REMOVE

    @OneToMany(mappedBy = "comment", cascade = CascadeType.REMOVE)
    private List<Comment> comments = new ArrayList<>();

    CascadeType은 상위 엔티티에서 발생한 작업을 하위 엔티티까지 전파시킬때 타입을 설정하는것이다
    각 타입마다 기능이 다르지만 REMOVE일경우 상위 엔티티에서 삭제가 일어날경우 하위 엔티티까지 삭제를 하라는 코드이다
    상위 엔티티의 영속성을 하위 엔티티의 영속성에게 전달한다

삭제하지않고 특정 컬럼을 추가하기

위의 코드들은 연관된 내용을 깔끔하게 삭제하기때문에 관리하기는 편하다
하지만 글이 삭제가되도 댓글을 보고싶거나 모종의 사건으로 글이나 댓글을 복구해야될때
전부 삭제해버리면 복구하기 까다로워진다

그래서 나는 프로젝트를 할때 이 방법을 썼다

먼저 Post엔티티에 삭제된 시간을 나타내는 deleted_at 컬럼을 추가시킨다
해당컬럼은 기본적으로 null상태이고 만약 사용자가 해당 글을 삭제했다면 실제로 delete를 해버리는게 아니라 deleted_at에 삭제된 시간을 넣는다
그리고 post들을 불러올때 deleted_at이 null인 내용들만 불러온다

이렇게되면 사용자들은 사이트를 이용할때 post가 지워졌다고 생각을 하게되고 post를 삭제해도 실제로 삭제된게아니고 연관관계는 계속 남아있기때문에 그 글에 작성한 댓글들도 볼 수 있다.

하지만 이 방법의 단점은 삭제가 된게 아니기때문에 자원소모가 첫번째 방법보다 크다는 단점이 존재한다
그래도 댓글까지 삭제되는것을 바라지 않았기때문에 나는 이 방법이 더 좋은것 같다

profile
안녕하세요

0개의 댓글

관련 채용 정보