Cascade.REMOVE와 orphanRemoval=true의 차이는?

Alex·2025년 1월 7일
0

Plaything

목록 보기
67/118

Cascade는 엔티티간의 변화를 전파할 때 사용한다.
부모 엔티티를 저장, 삭제할때 자식 엔티티까지 같이 연쇄적으로 저장이나 삭제가 되게끔하는 속성을 설정할 수 있다.

유사한 개념으로 orphanRemoval 속성이 있는데
어떤 차이가 있는지 테스트해보자.

Cascade 테스트로 확인해보자

삭제가 전파될까?

@Test
    void test1(){
        CreateUserRequest request = new CreateUserRequest("fnel123", "123", "11");
        authServiceV1.creatUser(request);
        ProfileRegistration registration = new ProfileRegistration(
                "연호",
                "안녕",
                Gender.M,
                TOP,
                List.of(HUNTER, SPANKER),
                HUNTER,
                List.of(MARRIAGE_DS),
                LocalDate.now());
        profileFacadeV1.registerProfile(registration, "fnel123");
        

        List<PersonalityTrait> all = personalityTraitRepository.findAll();
        assertThat(all.size()).isEqualTo(2);

        ProfileResponse profile = profileFacadeV1.getProfileByLoginId("fnel123");
        profileRepository.deleteById(profile.id());

        List<PersonalityTrait> all2 = personalityTraitRepository.findAll();
        assertThat(all2).isEmpty();


    }
    

Profile과 PersonalityTrait List는
Casacade.ALL 관계로 묶여 있다.

Profile 레코드를 삭제할 때 아예 delete 쿼리가 나가지 않았다.

원인을 찾아보니 Profile과 연관관계를 맺은 일대일 엔티티가 있어서 그런 것으로 보인다.

일대일 연관관계인 유저와의 연관관계를 먼저 끊어주어야 한다.

그러면 아래처럼 Profile을 삭제하면 Delete 쿼리가 나가고, 자식 엔티티까지 삭제가 전파된다.

일대일 관계에서는 이렇게 한쪽의 참조를 끊어줘야 한다.

자식과의 관계를 끊으면?

      List<PersonalityTrait> all = personalityTraitRepository.findAll();
        assertThat(all.size()).isEqualTo(2);

        ProfileResponse profile = profileFacadeV1.getProfileByLoginId("fnel123");
        Profile pr = profileRepository.findById(profile.id()).get();
        pr.getPersonalityTrait().remove(0);

        List<PersonalityTrait> all2 = personalityTraitRepository.findAll();
        assertThat(all2.size()).isEqualTo(1);

단순히 자식과의 참조를 끊는것만으로는
자식을 삭제하는 Delete 쿼리가지 나가지 않는다.

orphanRemoval 테스트로 확인해보자

삭제가 전파될까?

이렇게 변경하고 Profile만 삭제하는 테스트를 해보자.

Profile을 삭제하면 자식에 대한 Delete 쿼리가 다 잘 나간다.

자식과의 관계를 끊으면?

자식과의 관계를 끊으면 자식을 삭제하는 delete 쿼리가 나간다.

고아 객체 옵션은 부모와 자식의 관계가 끊어지면 자식을 고아로 취급하고 자식을 삭제하는 것이다.

결론

Profile의은 성향, 관계 지향, 사진을 유저가 계속 변경할 수 있다.

orphanRemoval을 사용하면 부모와의 관계를 끊어주기만 해도 삭제가 되니 이를 이용하면 될 것 같다.

profile
답을 찾기 위해서 노력하는 사람

0개의 댓글