• 카테고리

    질문 & 답변
  • 세부 분야

    백엔드

  • 해결 여부

    미해결

CASCADE

23.03.05 00:26 작성 23.03.05 00:36 수정 조회수 340

0

안녕하세요 강사님

CASCADE 강의를 들으면서 공부 도중 여러가지 테스트를 해보면서 이해가 안되는 부분이 있어서요

제가 이해한 내용으로는 CASCADE를 사용하면 Parent 필드에 있는 children 도 연관관계의 주인의 기능을 할 수 있다고 이해했는데요

위 코드를 실행한 결과 findChild1은 삭제 되지 않고 db에 남아있었습니다.

또한 em.remove(findChild1)을 지우고 list.remove(0)을 넣어도 데이터가 그대로 남아 있었습니다.

CASCADE 속성은 ALL으로 사용했습니다.

질문 1

영속성컨텍스트에 child 객체 두개와 children 내부에 child 객체 두개가 있어서 그런건가요?

질문2

그리고 고아객체 강의를 보고 이해가 안되는게

CascadeType.ALL + orphanRemoval=true 을 쓰는 것과

CascadeType.ALL 만 쓰는 것에 차이가 있을까요?

 

 

답변 1

답변을 작성해보세요.

0

y2gcoder님의 프로필

y2gcoder

2023.03.05

안녕하세요, 강민승 님. 공식 서포터즈 y2gcoder 입니다.

Cascade 부분은 많이 헷갈리는 부분입니다.

지금 질문해주신 즉시 로딩과 지연 로딩 다음의 영속성 전이(CASCADE)와 고아 객체 편을 진행하시면서 질문을 주신 것이라 생각합니다.

1)

먼저 제시해주신 위의 코드로 Cascade를 테스트할 수는 없을 것 같습니다.

해당 강의대로

@Entity 
public class Parent {
  @Id
  @GeneratedValue
  private Long id;

  private String name;

  @OneToMany(mappedBy = "parent", cascade = CascadeType.ALL)
  private List<Child> childList = new ArrayList();

  //... 생략
}
@Entity
public class Child {
  @Id
  @GeneratedValue
  private Long id;

  private String name;

  @ManyToOne
  @JoinColumn(name = "parent_id")
  private Parent parent;

  //... 생략
}

위와 같이 설정해주셨다면, 위의 뜻은 Parent의 영속성 상태를 변경할 때 관계를 맺은(==childList에 있는) Child들의 영속성도 같이 변경해주겠다는 뜻입니다.

그러면 테스트 코드를

저장

Child child1 = new Child();
Child child2 = new Child();

Parent parent = new Parent();
parent.addChild(child1);
parent.addChild(child2);

em.persist(parent); 영속성 전이 때문에 child1, child2도 같이 persist 된다.

 

삭제

Child child1 = new Child();
Child child2 = new Child();

Parent parent = new Parent();
parent.addChild(child1);
parent.addChild(child2);

em.persist(parent); //영속성 전이(CasacadeType.ALL) 덕분에 child1, child2도 같이 persist 된다.

em.flush();
em.clear();

Parent findParent = em.find(Parent.class, parent.getId());
em.remove(findParent); //영속성 전이(CascadeType.ALL) 덕분에 parent만 지우는 게 아니라 child1, child2도 같이 remove한다.

 

이런 식으로 영속성 전이를 관리하는 parent 객체를 중심으로 테스트하시는 게 맞습니다.

 

2)

orphanRemoval 옵션은 말 그대로 고아 객체는 지울 것인지 묻는 옵션이라고 생각해주시면 됩니다.

자식 객체가 부모 객체와의 연관관계가 끊어지면 고아 객체 상태가 되고 orphanRemoval=true 옵션은 해당 상태가 된 객체를 자동으로 삭제해주는 옵션입니다. 이 부분은 언뜻 보기에 CascadeType.REMOVE랑 차이가 없어보일 수 있으나 큰 차이가 있습니다.

해당 내용에 대한 것은 정말 잘 정리되어있는 글이 있어서 첨부해드리겠습니다. 참고해보셨으면 좋겠습니다.

https://tecoble.techcourse.co.kr/post/2021-08-15-jpa-cascadetype-remove-vs-orphanremoval-true/



감사합니다.