• 카테고리

    질문 & 답변
  • 세부 분야

    백엔드

  • 해결 여부

    미해결

연관관계 주인과 변경감지 그리고 cascade

24.01.15 22:09 작성 조회수 180

0

=========================================
[질문 템플릿]
1. 강의 내용과 관련된 질문인가요? (예
2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/
3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예

[질문 내용]
강의 14분 26초에서

 

Order의 cancel() 메서드 내부에 OrderStatus 변경은 변경 감지로 변경되는것을 이해하고 있습니다.

 

그리고 for loop 내부에서

    public void cancel() {
        if (delivery.getStatus() == COMPLETE) {
            throw new IllegalStateException("이미 배송완료된 상품은 취소가 불가능합니다");
        }

        this.setStatus(CANCEL);
        for (OrderItem orderItem : orderItems) {
            orderItem.cancel();
        }
    }

orderItem.cancel() 메서드가 호출되고 있습니다. orderItem.cancel()에서는 item 엔티티를 변경하고 있는데

    // 비즈니스 로직
    public void cancel() {
        getItem().addStock(count);
    }

궁금한 점은 item 엔티티가 변경이 가능한것은 orderItem이 FK를 갖고 있는 연관관계의 주인이기 때문인가요?

 

만약 item이 아닌 orderItem의 필드가 변경된다면 변경 감지가 가능할까요? orderItem이 order의 FK를 가지고 있고 반대로 Order는 orderItem의 FK갖지 않기 때문에 읽기만 가능한걸로 알고 있습니다.

 

질문이 좀 복잡해졌네요. 정리하자면

 

Q1. order.cancel() 메서드 내부에서 orderItem.cance() 메서드를 호출합니다. 만약 orderItem.cancel()이 orderItem의 필드롤 수정한다면 DB에 반영이 될까요? 지금까지 배운내용이라면 연관관계의 주인이 OrderItem이기 때문에 읽기만 가능하다고 배웠습니다.

 

Q2. 질문 1 상황에서 order 필드의 OrderItems에 cascade all이 붙어있다면 order에서 OrderItem을 수정이 가능할까요?

 

Q3. 만약 질문 1에서 읽기만 가능한게 맞다면 Order.cancel()이 orderItem.cancel()을 호출하고 차례로 item 엔티티를 수정하는 경우

order -> orderItem은 읽기만 가능하지만 orderItem -> item은 수정이 가능한 연관관계의 주인이기때문에 타고타고 넘어가서 수정이 가능한걸까요?

 

 

답변 2

·

답변을 작성해보세요.

1

안녕하세요. gukin.dev

먼저 2가지를 명확하게 분리해서 이해해야 합니다.

1. 엔티티는 스스로의 데이터를 변경 감지를 통해서 변경할 수 있습니다.

2. 연관관계의 주인은 FK의 값을 업데이트 할 때 사용하는 기능입니다. 엔티티 자신의 기능을 변경하는 기능이 아닙니다.

Q1. 여기서 읽기라는 것은 연관관계가 있는 엔티티를 읽어올 수 있다는 뜻입니다. 읽어온 엔티티는 영속 상태가 되고, 본인 스스로의 데이터를 변경할 수 있습니다.

Q2. Q3 cascade all과 무관하게 엔티티는 본인 스스로의 데이터를 변경할 수 있습니다.

감샇바니다.

0

인프런 AI 인턴님의 프로필

인프런 AI 인턴

2024.01.15

안녕하세요, 인프런 AI 인턴입니다.

gukin.dev 님의 질문에 대해 관련 내용을 정리하여 답변드립니다.

질문 내용은 크게 연관관계 주인, 변경 감지, 그리고 cascade에 대한 개념적인 혼동에 관한 것입니다. 각각에 대한 요약은 다음과 같습니다:

  1. 연관관계 주인은 JPA에서 외래 키를 관리하는 엔티티를 말합니다. 변경 감지 기능(Dirty Checking)은 영속성 컨텍스트에 존재하는 엔티티의 상태 변화를 찾아내어 데이터베이스에 업데이트하는 JPA의 기능입니다. 이것은 연관관계의 주인 여부와 관계없이 적용됩니다.

  2. cascade 옵션은 한 엔티티의 영속성 상태 변화를 연계된 엔티티에 전파하는 옵션입니다. 예를 들어 CascadeType.ALL 옵션이 설정되어 있는 경우, 부모 엔티티를 저장할 때(persist) 자식 엔티티도 함께 저장됩니다.

이제 구체적으로 질문에 답변드리겠습니다.

Q1. order.cancel() 내에서 호출되는 orderItem.cancel() 메서드가 orderItem의 필드를 수정하더라도, OrderItem 엔티티가 영속 상태라면 변경 감지가 발동하여 데이터베이스에 업데이트 됩니다. OrderItem이 연관관계의 주인인지 여부는 변경 감지에 영향을 주지 않습니다.

Q2. Order 엔티티의 orderItems 필드에 cascade = CascadeType.ALL이 설정되어 있다면, Order 엔티티를 저장할 때 관련된 OrderItem 엔티티도 함께 영속 상태가 되므로, 추후 이 엔티티들의 변경 사항이 cascade 옵션에 의해 자동으로 데이터베이스에 반영됩니다.

Q3. 영속 상태의 엔티티를 수정할 경우 cascade 설정과는 무관하게 변경 감지가 발생합니다. 따라서 order.cancel()에서 orderItem.cancel()을 호출하고, orderItem.cancel()에서 item 엔티티의 변경 사항(orderItem 혹은 item 내 필드 변경)이 있을 경우 해당 사항은 영속성 컨텍스트에 의해 데이터베이스에 반영됩니다.

유사한 답변 링크를 몇 가지 참조해드립니다:
- 변경 감지와 cascade 질문
- 해당 답변에서는 조회한 엔티티가 영속 상태가 되고, 변경 감지가 영속상태의 엔티티에서 발생한다고 설명하고 있으며, cascade와 변경 감지의 차이점에 대해 설명합니다.
- 연관관계의 주인이 아니더라도 Cacade 옵션으로 인한 persist 전파 설명
- 이 답변에서는 연관관계의 주인과 cascade 옵션의 개념을 설명합니다.

위 링크들을 참조하여 각 상황에서 영속성 전파와 변경 감지가 어떻게 작동하는지 이해하실 수 있을 것입니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.