BookLink 프로젝트를 진행하던 중,
게시판의 글을 지우는 순간 그에 해당하는 좋아요, 댓글 및 댓글의 좋아요를 지워야 했다.
다른 프로젝트라면 초반에 데이터베이스를 설계하면서 on delete cascade 조건을 붙여두었겠지만, 이 프로젝트에서는 그러지 못했고 JPA 사용이 처음이라 낯선 부분도 있었다. 즉 외래키 삭제 및 수정에 대한 대안을 따로 설정해두지 않았기 때문에 추가로 설정해주어야 했다.
on delete cascade
를 JPA로 적용하는 방식에는 두 가지가 있다.
1. 삭제되는 대상(부모)에
@OnDelete(action=OnDeleteAction.CASCADE)
붙여주기
2. 삭제당하는 대상(자식)의@OneToMany
옵션에cascade=CascadeType.REMOVE
붙여주기
해당 방법들의 작동 원리를 살펴보자.
위 어노테이션을 부모 대상의 컬럼에 붙여주면, 테이블이 생성되면서 on delete cascade
를 붙여준다. 우리가 직접 데이터베이스를 설계하고 연관관계를 매핑하면서 흔히 사용되는 방식이다. DDL 명령어를 통해 설정해준다고 생각하면 된다.
하지만 이미 존재하는 엔티티에 어노테이션을 추가하니, hibernate의 ddl-auto를 update로 설정했음에도 테이블은 업데이트 되지 않았다.
따라서 해당되는 테이블들을 임의로 drop한 후 JPA를 통해 새로 테이블을 생성시켰다.
위 어노테이션을 자식 대상의 컬럼에 붙여주면, DDL 명령어를 통해 조건을 붙여주는 것이 아닌
JPA가 cascade 방식으로 인해 삭제되어야 할 레코드들을 찾아 연쇄적으로 쿼리를 날려 삭제를 진행한다. 즉 참조된 레코드의 수만큼 쿼리가 생성된다.
위 두 방법 중 나는 첫번째 방법을 택했다.
이유는 두 가지이다.
첫째, 일대다 관계에서 가짜 매핑인 @OneToMany
를 따로 적지 않음
둘째, 여러 개의 쿼리 생성보다는 데이터베이스의 역량으로 처리되는 게 나을 것 같다는 생각
아래는 나의 예시로, 게시글이 삭제될 시 댓글(reply)도 함께 삭제되는 코드이다.
@ManyToOne
@JoinColumn(name = "reply_id")
@OnDelete(action = OnDeleteAction.CASCADE)
private BookClubReply reply;
글 잘 봤습니다.