[JPA] 양방향 테스트

타미·2020년 10월 13일
0

상황

Instagram(One), InstagramPost(Many)
ManyToOne이 주인일 때

주인이 아닌 쪽에서는 데이터를 수정할 수 없다.

    @DisplayName("양방향 테스트")
    @Test
    void test() {
        InstagramPost instagramPost = InstagramPost.builder().build();
        Instagram instagram = Instagram.builder().build();
        instagram.instagramPosts.add(instagramPost);
        instagramRepository.save(instagram);
    }
Hibernate: 
    insert 
    into
        instagram
        (created_date, modified_date, hashtag_count, hashtag_name, place_id) 
    values
        (?, ?, ?, ?, ?)

저장 안되쥬


@Entity

class Emp {

@OneToOne(orphanRemoval=true)

private Addr addr;

}

Emp 엔티티가 삭제될 때 참조가 끊어진 연관된 Addr 엔티티도 삭제하라는 의미이며 DB에서도 삭제되는데 참조(연결)가 끊어진 Addr 객체는 DB에서도 삭제된다는 뜻이다.

@Entity

class Emp {

@OneToOne(cascade=CascadeType.REMOVE)

private Addr addr;

}

Emp 엔티티가 삭제될 때 연관된 Addr 엔티티도 삭제하라는 의미이며 DB에서도 삭제된다.

고아객체는 연관관계의 주인쪽에 있던 아니던 지워진다.

연관관계의 주인이 아닌 Instagram 쪽에서 데이터를 지워보자.

    public void setUp1() {
        Instagram instagram = instagramRepository.save(Instagram.builder().build());
        InstagramPost instagramPost = InstagramPost.builder().instagram(instagram).build();
        instagramPostRepository.save(instagramPost);
    }

    @Transactional
    public void setUp2() {
        Instagram savedInstagram = instagramRepository.findById(1L).get();
        List<InstagramPost> instagramPosts = savedInstagram.instagramPosts;
        instagramPosts.size();
        instagramPosts.remove(0);
        instagramRepository.save(savedInstagram);
    }

    @DisplayName("ManyToOne 저장 테스트")
    @Test
    void insertTest() {
        setUp1();
        setUp2();
        Instagram savedInstagram2 = instagramRepository.findById(1L).get();
        assertThat(savedInstagram2.instagramPosts).hasSize(1);
    }
public class Instagram {
    @OneToMany(fetch = FetchType.EAGER, mappedBy = "instagram", orphanRemoval = true)
    public List<InstagramPost> instagramPosts = new ArrayList<>();
...
}

삭제된다 ㅇㅇ

public class Instagram {
    @OneToMany(fetch = FetchType.EAGER, mappedBy = "instagram", orphanRemoval = true, cascade = CascadeType.ALL)
    public List<InstagramPost> instagramPosts = new ArrayList<>();
...
}

삭제 된다 ㅇㅇ

public class Instagram {
    @OneToMany(fetch = FetchType.EAGER, mappedBy = "instagram", cascade = CascadeType.ALL)
    public List<InstagramPost> instagramPosts = new ArrayList<>();
...
}

삭제 안된다 ㅇㅇ

CASCADE 속성도 연관관계의 주인이던 아니던 적용된다.

public class Instagram {
    @OneToMany(fetch = FetchType.EAGER, mappedBy = "instagram", cascade = CascadeType.ALL)
    public List<InstagramPost> instagramPosts = new ArrayList<>();
...
}

CASCADE REMOVE가 적용되었기 때문에, instagram이 지워지면 instagramPost도 지워진다.


    public void setUp1() {
        Instagram instagram = instagramRepository.save(Instagram.builder().build());
        InstagramPost instagramPost = InstagramPost.builder().instagram(instagram).build();
        instagramPostRepository.save(instagramPost);
    }

    @Transactional
    public void setUp2() {
        Instagram savedInstagram = instagramRepository.findById(1L).get();
        instagramRepository.delete(savedInstagram);
    }

    @DisplayName("ManyToOne 저장 테스트")
    @Test
    void insertTest() {
        setUp1();
        setUp2();
        int size = instagramPostRepository.findAll().size();
        assertThat(size).isZero();
    }

Cascadetype.REMOVE 와 orphanRemoval = true

Instagram에 CASCADE, orphanRemoval을 적용하고 InstagramPost가 있을 때,

instagramRepository.remove(instagram);

  • CASCADE.REMOVE
    • instagramPost 지원진다.
  • orpahnRemoval
    • instagramPost 지워진다.

instagram.instagramPosts.get(0) = null;

  • CASCADE.REMOVE
    • instagramPost 지워지지 않는다.
  • orpahnRemoval
    • instagramPost 지워진다.

고아객체, CASCADE : 연관관계와 무관하다.

profile
IT's 호기심 천국

0개의 댓글