문제

간단한 문제가 있습니다 @OneToMany 상위 엔터티와 하위 엔터티 간의 매핑입니다.모두 잘 작동합니다. 컬렉션에서 해당 하위 레코드를 제거해도 해당 하위 레코드만 삭제되지 않습니다.

부모:

@Entity
public class Parent {
    @Id
    @Column(name = "ID")
    private Long id;

    @OneToMany(cascade = {CascadeType.ALL}, mappedBy = "parent")
    private Set<Child> childs = new HashSet<Child>();

 ...
}

아이:

@Entity
public class Child {
    @Id
    @Column(name = "ID")
    private Long id;

    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name="PARENTID", nullable = false)
    private Parent parent;

  ...
}

이제 하위 세트에서 하위 항목을 삭제해도 데이터베이스에서는 삭제되지 않습니다.무효화하려고 했으나 child.parent 참조했지만 그것도 작동하지 않았습니다.

엔터티는 웹 애플리케이션에서 사용되며 삭제는 Ajax 요청의 일부로 발생합니다.저장 버튼을 눌렀을 때 삭제된 하위 항목 목록이 없으므로 암시적으로 삭제할 수 없습니다.

도움이 되었습니까?

해결책

JPA의 동작이 정확합니다(의미 사양에 따라):단순히 OneToMany 컬렉션에서 개체를 제거했다고 해서 개체가 삭제되는 것은 아닙니다.이를 수행하는 공급업체별 확장 기능이 있지만 기본 JPA는 이를 지원하지 않습니다.

부분적으로 이는 JPA가 컬렉션에서 제거된 항목을 삭제해야 하는지 실제로 알지 못하기 때문입니다.객체 모델링 측면에서 이는 다음과 같은 차이점이 있습니다. 구성 그리고 "집계*.

~ 안에 구성, 하위 엔터티는 상위 엔터티 없이는 존재하지 않습니다.전형적인 예는 House와 Room 사이입니다.집을 삭제하면 방도 삭제됩니다.

집합 보다 느슨한 종류의 연관이며 코스 및 학생으로 대표됩니다.강좌를 삭제해도 학생은 여전히 ​​존재합니다(아마도 다른 강좌에 있을 것입니다).

따라서 공급업체별 확장을 사용하여 이 동작을 강제하거나(사용 가능한 경우) 자식을 명시적으로 삭제하고 부모 컬렉션에서 제거해야 합니다.

나는 다음을 알고 있습니다:

다른 팁

Cletus의 대답 외에도 JPA 2.0, 2010 년 12 월 이후 최종 orphanRemoval 속성을 켜십시오 @OneToMany 주석. 자세한 내용은 이것을 참조하십시오 블로그 항목.

사양이 비교적 새롭기 때문에 모든 JPA 1 제공 업체가 최종 JPA 2 구현을 갖는 것은 아닙니다. 예를 들어, 최대 절전 모드 3.5.0- 베타 -2 릴리스 아직이 속성을 지원하지 않습니다.

당신은 이것을 시도 할 수 있습니다 :

@OneToOne(orphanRemoval=true) or @OneToMany(orphanRemoval=true).

설명했듯이 JPA로 원하는 것을 할 수는 없으므로 Hibernate.cascade 주석을 사용했습니다. 이와 함께 부모 클래스의 관련 코드는 다음과 같습니다.

@OneToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH}, mappedBy = "parent")
@Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE,
            org.hibernate.annotations.CascadeType.DELETE,
            org.hibernate.annotations.CascadeType.MERGE,
            org.hibernate.annotations.CascadeType.PERSIST,
            org.hibernate.annotations.CascadeType.DELETE_ORPHAN})
private Set<Child> childs = new HashSet<Child>();

부모를 삭제했을 것이기 때문에 '모두'를 간단하게 사용할 수 없었습니다.

여기서 Cascade는 제거의 맥락에서 부모를 제거하면 어린이가 제거되었음을 의미합니다. 협회가 아닙니다. Hibernate를 JPA 제공 업체로 사용하는 경우 사용 할 수 있습니다. 최대 절전 모드 특정 캐스케이드.

당신은 이것을 시도 할 수 있습니다 :

@OneToOne(cascade = CascadeType.REFRESH) 

또는

@OneToMany(cascade = CascadeType.REFRESH)
@Entity 
class Employee {
     @OneToOne(orphanRemoval=true)
     private Address address;
}

보다 여기.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top