테스트 코드

        var newChannel = Channel.builder().name("new-channel").build();
        var newThread = Thread.builder().message("new-message").build();
        var newThread1 = Thread.builder().message("장마 끝!!").build();

        newThread.setChannel(newChannel);
        newThread1.setChannel(newChannel);

        var savedChannel = channelRepository.insertChannel(newChannel);
        var savedThread = threadRepository.insertThread(newThread);
        var savedThread1 = threadRepository.insertThread(newThread1);

        // when
        var foundChannel = channelRepository.selectChannel(savedChannel.getId());
        foundChannel.getThreads().remove(savedThread);

 

 

1. CascadeType.ALL만 적용한 경우

    @OneToMany(mappedBy = "channel", cascade = CascadeType.ALL)
    private Set<Thread> threads = new LinkedHashSet<>(); // 중복 x 순서 o
Hibernate: 
    insert 
    into
        channel
        (name, type) 
    values
        (?, ?)
Hibernate: 
    insert 
    into
        thread
        (channel_id, message) 
    values
        (?, ?)
Hibernate: 
    insert 
    into
        thread
        (channel_id, message) 
    values
        (?, ?)

delete 쿼리가 날아가지 않는다.

 

 

 

2. CascadeType.ALL과 orphanRemoval = true 둘 다 적용한 경우

    @OneToMany(mappedBy = "channel", cascade = CascadeType.ALL, orphanRemoval = true)
    private Set<Thread> threads = new LinkedHashSet<>(); // 중복 x 순서 o
Hibernate: 
    insert 
    into
        channel
        (name, type) 
    values
        (?, ?)
Hibernate: 
    insert 
    into
        thread
        (channel_id, message) 
    values
        (?, ?)
Hibernate: 
    insert 
    into
        thread
        (channel_id, message) 
    values
        (?, ?)
Hibernate: 
    delete 
    from
        thread 
    where
        id=?

delete 쿼리가 날아가고 스레드 테이블에서 스레드가 삭제된다.

 

 

 

3. orphanRemoval = true 만 적용한 경우

Hibernate: 
    insert 
    into
        channel
        (name, type) 
    values
        (?, ?)
Hibernate: 
    insert 
    into
        thread
        (channel_id, message) 
    values
        (?, ?)
Hibernate: 
    insert 
    into
        thread
        (channel_id, message) 
    values
        (?, ?)

delete 쿼리가 날라가지 않는다.

 

 

Cascade.REMOVE 와 orphanRemoval 차이점

Cascade.REMOVE : 부모 엔티티를 em.remove로 직접 삭제하면 자식 엔티티도 삭제된다.

orphanRemoval : 부모 엔티티를 em.remove로 직접 삭제하면 자식 엔티티도 삭제된다. + 부모 엔티티의 리스트에서 어떤 요소를 삭제하면 그에 해당하는 자식 엔티티도 삭제된다. 즉, 리스트 요소의 영속성 전이도 해준다.

 

위 테스트 코드로 예를 들면 부모 객체인 savedChannel의 threads 안에 있는 savedThread를 제거하면 스레드 테이블에서도 해당 스레드가 삭제된다.

 

 

 

 

영속성 전이 최강 조합 : CascadeType.ALL + orphanRemoval = true 

위 두가지를 함께 설정하면 자식 엔티티의 라이프 사이클이 부모 엔티티와 동일해지며, 직접 자식 엔티티의 생명주기를 관리할 수 있게 되므로 자식 엔티티의 Repository 조차 없어도 된다. (따라서, 매핑 테이블에서 많이 쓰임)

 

 

 

Fetch(조회 시점)

FetchType

EAGER : 부모 조회 시 자식도 같이 조회

LAZY : 부모 조회시 부모만 조회, 자식은 필요할 때 따로 조회

'TIL > WEEK11' 카테고리의 다른 글

equals()로 객체 비교  (0) 2023.07.25

문제점

프로젝트를 진행하면서 게시글을 수정, 삭제 api에서 작성자 확인이 제대로 되지 않는 문제가 발생했다.

    @Transactional
    public PostResponseDto updatePost(Long id, PostRequestDto requestDto, User user) {
        Post post = findPost(id);
        //게시글 작성자와 요청자가 같은지 또는 관리자인지 체크 -> 아닐시 예외 발생
        // 해당 post의 작성자가 맞는지 확인
        if (user.equals(post.getUser()) || user.getRole().equals(UserRoleEnum.ADMIN)) {
            // requestDto로부터 받은 게시글의 제목과 내용으로 해당 post 내용 수정하기
            post.setTitle(requestDto.getTitle());
            post.setContent(requestDto.getContent());
            Category category = categoryRepository.findById(requestDto.getCategoryId()).orElseThrow(() ->
                    new IllegalArgumentException("선택한 게시글이 존재하지 않습니다"));
            post.setCategory(category);


        } else {
            // 해당 post의 작성자가 아니라면 null 반환하기
            throw new RejectedExecutionException();
        }

        return new PostResponseDto(post);
    }

user.equals(post.getUser())가 계속 false로 나와 이런 문제가 발생했는데 원인은 User 클래스에 equals 메서드를 오버라이딩 해주지 않아서 발생한 거였다. 

 

 

 

해결방안

User 클래스에 @EqualsAndHashCode 어노테이션을 달아줌으로써 해결했다.

 

 

 

깨달은 점

두 객체를 equals 메서드로 비교하려면 오버라이딩 하는 걸 잊지 말자!

'TIL > WEEK11' 카테고리의 다른 글

Cascade.REMOVE 와 orphanRemoval  (0) 2023.07.27

+ Recent posts