JPA에서 CascadeType.REMOVE와 orphanRemoval의 차이점은 무엇입니까?


103

차이점은 무엇입니까

@OneToMany(cascade=REMOVE, mappedBy="customer")
public List<Order> getOrders() { ... }

@OneToMany(mappedBy="customer", orphanRemoval="true")
public List<Order> getOrders() { ... }

이 예제는 Java EE Tutorial에서 가져온 것이지만 여전히 세부 사항을 이해하지 못합니다.


고아 제거는 "상위"엔티티와의 관계가 파괴 될 때 종속 엔티티가 제거됨을 의미합니다.
Rahul Tripathi 2013 년

1
개념을 설명 할 수 있는 테스트 케이스를 작성 했습니다.
Martin Andersson 2014

답변:


153

에서 여기 : -

계단식 제거

참조 필드를 CascadeType.REMOVE (또는 REMOVE를 포함하는 CascadeType.ALL)로 표시하면 제거 작업이 해당 필드에서 참조하는 엔터티 개체에 자동으로 연결되어야 함을 나타냅니다 (여러 개체 개체는 컬렉션 필드에서 참조 할 수 있음).

@Entity
class Employee {
     :
    @OneToOne(cascade=CascadeType.REMOVE)
    private Address address;
     :
}

고아 제거

JPA 2는 @OneToOne 및 @OneToMany 주석의 orphanRemoval 요소를 사용하여 지정할 수있는보다 적극적인 추가 제거 계단식 모드를 지원합니다.

@Entity
class Employee {
     :
    @OneToOne(orphanRemoval=true)
    private Address address;
     :
}

차:-

두 설정의 차이점은 관계 연결 해제에 대한 응답입니다. 예를 들어 주소 필드를 null 또는 다른 주소 개체로 설정하는 경우입니다.

  • 경우 orphanRemoval = 사실 IS 지정한 연결이 끊긴 주소 인스턴스는 자동으로 제거됩니다. 이것은 소유자 개체 (예 : Employee)의 참조 없이는 존재하지 않아야하는 종속 개체 (예 : 주소)를 정리하는 데 유용합니다.
  • cascade = CascadeType.REMOVE 만 지정된 경우 관계 연결 해제는 제거
    작업 이 아니므로 자동 작업이 수행되지 않습니다 .

87

CascadeType.REMOVE과 의 차이점을 쉽게 이해할 수있는 방법 orphanRemoval=true입니다.

고아 제거의 경우 :를 호출 setOrders(null)하면 관련 Order엔티티가 db에서 자동으로 제거됩니다.

계단식 제거의 경우 :를 호출 setOrders(null)하면 관련 Order엔티티가 db에서 자동으로 제거 되지 않습니다 .


2
제거 === 삭제
Abdull

9

자식 엔터티와 부모 엔터티가 있다고 가정합니다. 부모는 여러 자녀를 가질 수 있습니다.

@Entity
class parent {
  //id and other fields
 @OneToMany (orphanRemoval = "true",cascade = CascadeType.REMOVE)
   Set<Person> myChildern;
}

orphanRemoval은 ORM 개념이며 자식이 고아인지 여부를 알려줍니다. 또한 데이터베이스에서 제거해야합니다.

부모로부터 액세스 할 수없는 자식은 고아가됩니다. 예를 들어 Person 객체 세트를 제거하거나 (빈 세트로 설정) 새 세트로 바꾸면 부모는 더 이상 이전 세트의 자식에 액세스 할 수 없으며 자식은 고아가되어 자식이 데이터베이스에서도 제거되었습니다.

CascadeType.REMOVE는 데이터베이스 수준 개념이며 상위 항목이 제거되었는지 여부와 하위 테이블의 모든 관련 레코드를 제거해야 함을 알려줍니다.


2

실제로 차이점은 데이터를 업데이트 (PATCH)하려고하는지 아니면 데이터를 완전히 대체 (PUT)하는지에 있습니다.

하자 당신이 삭제 말을 customer사용하는 것보다 cascade=REMOVE도 구성하고 유용한 것 같다 그 고객의 주문을 제거합니다.

@OneToMany(cascade=REMOVE, mappedBy="customer")
public List<Order> getOrders() { ... }

이제 당신이 업데이트 가정 해 봅시다 customerorphanRemoval="true"그 이전의 모든 주문을 삭제하고 제공 한 사람과 그들을 대체합니다. ( PUT기준 REST API)

@OneToMany(mappedBy="customer", orphanRemoval="true")
public List<Order> getOrders() { ... }

orphanRemoval오래된 명령이 없으면 보관됩니다. ( PATCH기준 REST API)


1

이 질문은 매우 일반적이기 때문에이 답변은 제가 블로그에 작성한 이 기사를 기반으로 합니다 .

CascadeType.REMOVE

CascadeType.REMOVE명시 적으로 구성 할 수 있는 전략 :

@OneToMany(
    mappedBy = "post",
    cascade = CascadeType.REMOVE
)
private List<PostComment> comments = new ArrayList<>();

또는 CascadeType.ALL전략 에서 암시 적으로 상속 :

@OneToMany(
    mappedBy = "post",
    cascade = CascadeType.ALL
)
private List<PostComment> comments = new ArrayList<>();

remove상위 엔티티에서 하위 엔티티로 작업 을 전파 할 수 있습니다 .

따라서 컬렉션 Post과 함께 상위 항목을 가져오고 항목을 comments제거하면 post:

Post post = entityManager.createQuery("""
    select p
    from Post p
    join fetch p.comments
    where p.id = :id
    """, Post.class)
.setParameter("id", postId)
.getSingleResult();

entityManager.remove(post);

Hibernate는 세 개의 delete 문을 실행할 것입니다.

DELETE FROM post_comment 
WHERE id = 2

DELETE FROM post_comment 
WHERE id = 3

DELETE FROM post 
WHERE id = 1

전략으로 PostComment인해 하위 엔티티가 삭제되었으며 이는 하위 엔티티도 CascadeType.REMOVE제거 된 것처럼 작동했습니다.

고아 제거 전략

orphanRemoval속성을 통해 설정해야하는 고아 제거 전략 :

@OneToMany(
    mappedBy = "post",
    cascade = CascadeType.ALL,
    orphanRemoval = true
)
private List<PostComment> comments = new ArrayList<>();

컬렉션에서 자식 엔터티를 제거 할 때 자식 테이블 행을 제거 할 수 있습니다.

따라서 컬렉션과 Post함께 엔티티를 로드 하고 comments컬렉션에서 첫 번째 항목 PostComment을 제거하면 comments:

Post post = entityManager.createQuery("""
    select p
    from Post p
    join fetch p.comments c
    where p.id = :id
    order by p.id, c.id
    """, Post.class)
.setParameter("id", postId)
.getSingleResult();

post.remove(post.getComments().get(0));

Hibernate는 관련 post_comment테이블 행에 대해 DELETE 문을 실행할 것입니다 .

DELETE FROM post_comment 
WHERE id = 2

이 주제에 대한 자세한 내용은 이 기사 도 확인하십시오 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.