[JPA] on delete cascade JPA에 적용하기

SCY·2023년 7월 26일
2
post-thumbnail

BookLink 프로젝트를 진행하던 중,
게시판의 글을 지우는 순간 그에 해당하는 좋아요, 댓글 및 댓글의 좋아요를 지워야 했다.

다른 프로젝트라면 초반에 데이터베이스를 설계하면서 on delete cascade 조건을 붙여두었겠지만, 이 프로젝트에서는 그러지 못했고 JPA 사용이 처음이라 낯선 부분도 있었다. 즉 외래키 삭제 및 수정에 대한 대안을 따로 설정해두지 않았기 때문에 추가로 설정해주어야 했다.

on delete cascade를 JPA로 적용하는 방식에는 두 가지가 있다.

1. 삭제되는 대상(부모)에 @OnDelete(action=OnDeleteAction.CASCADE) 붙여주기
2. 삭제당하는 대상(자식)의 @OneToMany 옵션에 cascade=CascadeType.REMOVE 붙여주기

해당 방법들의 작동 원리를 살펴보자.

⚡ @OnDelete(action = OnDeleteAction.CASCADE)

위 어노테이션을 부모 대상의 컬럼에 붙여주면, 테이블이 생성되면서 on delete cascade를 붙여준다. 우리가 직접 데이터베이스를 설계하고 연관관계를 매핑하면서 흔히 사용되는 방식이다. DDL 명령어를 통해 설정해준다고 생각하면 된다.

하지만 이미 존재하는 엔티티에 어노테이션을 추가하니, hibernate의 ddl-auto를 update로 설정했음에도 테이블은 업데이트 되지 않았다.

따라서 해당되는 테이블들을 임의로 drop한 후 JPA를 통해 새로 테이블을 생성시켰다.

⚡ @OneToMany(mappedBy = "parent", cascade = CascadeType.REMOVE)

위 어노테이션을 자식 대상의 컬럼에 붙여주면, DDL 명령어를 통해 조건을 붙여주는 것이 아닌
JPA가 cascade 방식으로 인해 삭제되어야 할 레코드들을 찾아 연쇄적으로 쿼리를 날려 삭제를 진행한다. 즉 참조된 레코드의 수만큼 쿼리가 생성된다.

나의 선택

위 두 방법 중 나는 첫번째 방법을 택했다.

이유는 두 가지이다.

첫째, 일대다 관계에서 가짜 매핑인 @OneToMany를 따로 적지 않음
둘째, 여러 개의 쿼리 생성보다는 데이터베이스의 역량으로 처리되는 게 나을 것 같다는 생각

아래는 나의 예시로, 게시글이 삭제될 시 댓글(reply)도 함께 삭제되는 코드이다.

    @ManyToOne
    @JoinColumn(name = "reply_id")
    @OnDelete(action = OnDeleteAction.CASCADE)
    private BookClubReply reply;
profile
성장 중독 | 서버, 데이터, 정보 보안을 공부합니다.

1개의 댓글

comment-user-thumbnail
2023년 7월 26일

글 잘 봤습니다.

답글 달기