IT

캐스케이드 삭제시 JPA 2.0 orphanRemoval = true VS

lottoking 2020. 5. 29. 08:10
반응형

캐스케이드 삭제시 JPA 2.0 orphanRemoval = true VS


JPA 2.0 orphanRemoval속성 에 대해 약간 혼란 스럽습니다 .

JPA 공급자의 DB 생성 도구를 사용 ON DELETE CASCADE하여 특정 관계에 대한 기본 데이터베이스 DDL을 만들 때 이것이 필요하다는 것을 알 수 있습니다 .

그러나 DB가 존재하고 이미 ON DELETE CASCADE관계 가있는 경우 삭제를 적절하게 단계 화하기에 충분하지 않습니까? 무엇을 않는 orphanRemoval추가합니까?

건배


orphanRemoval와는 아무런 관련이 없습니다 ON DELETE CASCADE.

orphanRemoval전적으로 ORM에 특정한 것 입니다. 더 이상 "부모"엔터티에서 참조되지 않을 때 (예 : 부모 엔터티의 해당 컬렉션에서 하위 엔터티를 제거 할 때) "하위"엔터티가 제거되도록 표시합니다.

ON DELETE CASCADEA는 데이터베이스 고유의 건 은 "부모"행이 삭제 될 때, 그것은 데이터베이스에 "아이"행을 삭제합니다.


예를 들어 여기에 양식이 있습니다 .

Employee엔티티 객체가 제거되고, 제거 작업은 참조에 종속되는 Address엔티티 객체. 이와 관련하여, orphanRemoval=truecascade=CascadeType.REMOVE동일하며, 만약 orphanRemoval=true지정된, CascadeType.REMOVE중복.

두 설정의 차이점은 관계를 끊는 것에 대한 응답입니다. 예를 들어, 주소 필드 null를 다른 Address개체 로 설정 하거나 다른 개체 로 설정하는 경우 등이 있습니다.

  • 경우 orphanRemoval=trueIS 지정한 분리 Address인스턴스가 자동으로 제거됩니다. 이는 Address소유자 객체 (예 :)의 참조없이 존재하지 않아야 하는 종속 객체 (예 :)를 정리하는 데 유용합니다 Employee.

  • cascade=CascadeType.REMOVE지정된 경우에만 관계를 끊는 것이 제거 작업이 아니므로 자동 작업이 수행되지 않습니다.

고아 제거 결과로 댕글 링 참조를 피하려면이 기능은 개인 비공유 종속 개체를 보유하는 필드에 대해서만 활성화해야합니다.

이것이 더 명확 해지기를 바랍니다.


컬렉션에서 하위 엔터티를 제거하는 순간 해당 하위 엔터티도 DB에서 제거됩니다. orphanRemoval은 또한 부모를 변경할 수 없음을 의미합니다. 직원이있는 부서가있는 경우 해당 직원을 제거하여 다른 부서에 배치 한 경우, 해당 직원을 플러시 / 커밋 할 때 데이터베이스에서 실수로 제거했습니다 (둘 중 먼저 발생). 그 부모의 자녀가 다른 부모에게 존재하지 않는 것이 확실한 한 사기는 orphanRemoval을 true로 설정하는 것입니다. orphanRemoval을 켜면 캐스케이드 목록에 자동으로 제거가 추가됩니다.


DDL에 대한 동등한 JPA 맵핑 ON DELETE CASCADEcascade=CascadeType.REMOVE입니다. 고아 제거는 "부모"개체와의 관계가 파괴 될 때 종속 개체가 제거됨을 의미합니다. 예를 들어 @OneToMany항목 관리자 에서 자식 을 명시 적으로 제거하지 않고 관계 에서 자식을 제거하는 경우를 예로들 수 있습니다.


차이점은 다음과 같습니다.
-orphanRemoval = true : "자식"엔터티가 더 이상 참조되지 않으면 제거됩니다 (부모가 제거되지 않을 수 있음).
-CascadeType.REMOVE : "자식"개체는 "부모"가 제거 된 경우에만 제거됩니다.


@GaryK의 대답은, 내가 설명을 찾는 시간을 절대적으로 큰 썼다되는 orphanRemoval = trueCascadeType.REMOVE그리고 그것은 나를 이해할 수있었습니다.

요약 : 객체 ( )를 삭제 하고 자식 객체도 제거하려는 경우 에만orphanRemoval = true 동일하게 작동합니다 .CascadeType.REMOVE entityManager.delete(object)

완전히 다른 상황에서, 우리가 같은 데이터를 가져 와서 List<Child> childs = object.getChilds()자식 ( entityManager.remove(childs.get(0)) 을 제거 orphanRemoval=true하면 해당 엔티티 childs.get(0)가 데이터베이스에서 삭제됩니다.


고아 제거는 다음과 같은 시나리오에서 ON DELETE CASCADE와 동일한 효과를 갖습니다. Student 테이블이 id_guide를 FK로 갖도록 Student와 Guide 테이블 간의 외래 키 관계.

    @Entity
    @Table(name = "student", catalog = "helloworld")
    public class Student implements java.io.Serializable {
     @Id
     @GeneratedValue(strategy = IDENTITY)
     @Column(name = "id")
     private Integer id;

    @ManyToOne(cascade={CascadeType.PERSIST,CascadeType.REMOVE})
    @JoinColumn(name = "id_guide")
    private Guide guide;

// 부모 엔티티

    @Entity
    @Table(name = "guide", catalog = "helloworld")
    public class Guide implements java.io.Serializable {

/**
 * 
 */
private static final long serialVersionUID = 9017118664546491038L;

@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "id", unique = true, nullable = false)
private Integer id;

@Column(name = "name", length = 45)
private String name;

@Column(name = "salary", length = 45)
private String salary;


 @OneToMany(mappedBy = "guide", orphanRemoval=true) 
 private Set<Student> students = new  HashSet<Student>(0);

In this scenario, the relationship is such that student entity is the owner of the relationship and as such we need to save the student entity in order to persist the whole object graph e.g.

    Guide guide = new Guide("John", "$1500");
    Student s1 = new Student(guide, "Roy","ECE");
    Student s2 = new Student(guide, "Nick", "ECE");
    em.persist(s1);
    em.persist(s2);

Here we are mapping the same guide with two different student objects and since the CASCADE.PERSIST is used , the object graph will be saved as below in the database table(MySql in my case)

STUDENT table:-

ID Name Dept Id_Guide

1     Roy     ECE    1

2    Nick    ECE    1

GUIDE Table:-

ID NAME Salary

1    John     $1500

and Now if I want to remove one of the students, using

      Student student1 = em.find(Student.class,1);
      em.remove(student1);

and when a student record is removed the corresponding guide record should also be removed, that's where CASCADE.REMOVE attribute in the Student entity comes into picture and what it does is ;it removes the student with identifier 1 as well the corresponding guide object(identifier 1). But in this example, there is one more student object which is mapped to the same guide record and unless we use the orphanRemoval=true attribute in the Guide Entity , the remove code above will not work.

참고URL : https://stackoverflow.com/questions/4329577/jpa-2-0-orphanremoval-true-vs-on-delete-cascade

반응형