Spring
[Spring] Cascade관계에서 추가로 활용하면 좋을 옵션 orphanRemoval
퉁그리
2022. 1. 18. 22:16
cascade에는 remove라는 옵션이 있다.
이는 부모 엔티티가 삭제되면 자식 엔티티가 삭제되는 옵션이다.
즉 부모가 자식의 삭제 생명주기를 관리하게 되는 것이다.
cascade의 persist까지 쓰게 된다면, 부모가 자식의 전체 생명주기를 관리하게 된다.
하지만 이 옵션들에는 구멍이 있는데, 바로 부모자식관계를 끊어 냈을 때 즉, 고아를 만들었을 때 삭제되지 않는다.
orphanRemoval 옵션없이 cascasde 옵션만 설정했을 때 자식관계를 끊어내봤다.
// JpaLearningTest.java
@DisplayName("CascadeType.REMOVE - 부모 엔티티(Team)에서 자식 엔티티(Member)를 제거하는 경우")
@Test
void cascadeType_Remove_InCaseOfMemberRemovalFromTeam() {
// given
Member member1 = new Member();
Member member2 = new Member();
Team team = new Team();
team.addMember(member1);
team.addMember(member2);
teamRepository.save(team);
// when
team.getMembers().remove(0);
// then
List<Team> teams = teamRepository.findAll();
List<Member> members = memberRepository.findAll();
assertThat(teams).hasSize(1);
assertThat(members).hasSize(2);
}
orphanRemoval
나가는 쿼리는 이와같다.
// DML
Hibernate:
insert
into
team
(id, name)
values
(null, ?)
Hibernate:
insert
into
member
(id, name, team_id)
values
(null, ?, ?)
Hibernate:
insert
into
member
(id, name, team_id)
values
(null, ?, ?)
자식관계를 끊어냈음에도 불구하고 딜리트쿼리가 나가지 않았다.
이때 orphanRemoval = true 옵션을 연관관계에 적용하면 딜리트 쿼리가 나간다.
// JpaLearningTest.java
@DisplayName("orphanRemoval = true - 부모 엔티티(Team)에서 자식 엔티티(Member)를 제거하는 경우")
@Test
void orphanRemoval_True_InCaseOfMemberRemovalFromTeam() {
// given
Member member1 = new Member();
Member member2 = new Member();
Team team = new Team();
team.addMember(member1);
team.addMember(member2);
teamRepository.save(team);
// when
team.getMembers().remove(0);
// then
List<Team> teams = teamRepository.findAll();
List<Member> members = memberRepository.findAll();
assertThat(teams).hasSize(1);
assertThat(members).hasSize(1);
}
// DML
Hibernate:
insert
into
team
(id, name)
values
(null, ?)
Hibernate:
insert
into
member
(id, name, team_id)
values
(null, ?, ?)
Hibernate:
insert
into
member
(id, name, team_id)
values
(null, ?, ?)
Hibernate:
select
team0_.id as id1_1_,
team0_.name as name2_1_
from
team team0_
Hibernate:
delete
from
member
where
id=?
이렇게 딜리트쿼리가 나간다.
출처 : JPA CascadeType.REMOVE vs orphanRemoval = true (techcourse.co.kr)