[java] JPA에서 CascadeType.REMOVE와 orphanRemoval의 차이점은 무엇입니까?
차이점은 무엇입니까
@OneToMany(cascade=REMOVE, mappedBy="customer")
public List<Order> getOrders() { ... }
과
@OneToMany(mappedBy="customer", orphanRemoval="true")
public List<Order> getOrders() { ... }
이 예제는 Java EE Tutorial에서 가져온 것이지만 여전히 세부 사항을 이해하지 못합니다.
답변
에서 여기 : –
계단식 제거
참조 필드를 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 만 지정된 경우 관계 연결 해제는 제거
작업 이 아니므로 자동 작업이 수행되지 않습니다 .
답변
CascadeType.REMOVE
과 의 차이점을 쉽게 이해할 수있는 방법 orphanRemoval=true
입니다.
고아 제거의 경우 :를 호출 setOrders(null)
하면 관련 Order
엔티티가 db에서 자동으로 제거됩니다.
계단식 제거의 경우 :를 호출 setOrders(null)
하면 관련 Order
엔티티가 db에서 자동으로 제거 되지 않습니다 .
답변
자식 엔터티와 부모 엔터티가 있다고 가정합니다. 부모는 여러 자녀를 가질 수 있습니다.
@Entity
class parent {
//id and other fields
@OneToMany (orphanRemoval = "true",cascade = CascadeType.REMOVE)
Set<Person> myChildern;
}
orphanRemoval은 ORM 개념이며 자식이 고아인지 여부를 알려줍니다. 또한 데이터베이스에서 제거해야합니다.
부모로부터 액세스 할 수없는 자식은 고아가됩니다. 예를 들어 Person 객체 세트를 제거하거나 (빈 세트로 설정) 새 세트로 바꾸면 부모는 더 이상 이전 세트의 자식에 액세스 할 수 없으며 자식은 고아가되어 자식이 데이터베이스에서도 제거되었습니다.
CascadeType.REMOVE는 데이터베이스 수준 개념이며 상위 항목이 제거되었는지 여부와 하위 테이블의 모든 관련 레코드를 제거해야 함을 알려줍니다.
답변
실제로 차이점은 데이터를 업데이트 (PATCH)하려고하는지 아니면 데이터를 완전히 대체 (PUT)하는지에 있습니다.
하자 당신이 삭제 말을 customer
사용하는 것보다 cascade=REMOVE
도 구성하고 유용한 것 같다 그 고객의 주문을 제거합니다.
@OneToMany(cascade=REMOVE, mappedBy="customer")
public List<Order> getOrders() { ... }
이제 당신이 업데이트 가정 해 봅시다 customer
과 orphanRemoval="true"
그 이전의 모든 주문을 삭제하고 제공 한 사람과 그들을 대체합니다. ( PUT
기준 REST API
)
@OneToMany(mappedBy="customer", orphanRemoval="true")
public List<Order> getOrders() { ... }
orphanRemoval
오래된 명령이 없으면 보관됩니다. ( PATCH
기준 REST API
)
답변
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
이 주제에 대한 자세한 내용은 이 기사 도 확인하십시오 .