2011-04-26 3 views
10

의 우리가 두 개의 엔티티하는 있다고 가정 해 봅시다와 B B가 같은에 대일 관계를 맺고은 다음과 같습니다JPA 또는 데이터베이스 캐스케이드 삭제를 허용해야합니까?

@Entity 
public class A { 
    @OneToMany(mappedBy="a_id") 
    private List<B> children; 
} 

@Entity 
public class B { 
    private String data; 
} 

을 지금, 나는이 객체를 삭제로 삭제를 계단식으로 원하는 모든 아이들 (B). 두 가지 방법이 있습니다 :

1) JPA가 데이터베이스에서 A 객체를 제거하기 전에 모든 자식을 제거하도록하여 cascade=CascadeType.ALL, orphanRemoval=true을 OneToMany 주석에 추가하십시오.

2) 클래스를 그대로 두어 데이터베이스가 삭제되도록합니다.

나중 옵션을 사용하는 데 문제가 있습니까? Entity Manager가 이미 삭제 된 객체에 대한 참조를 유지하게합니까? 옵션 2를 선택하는 이유 중 하나는 옵션 A가 제거를 위해 n + 1 개의 SQL 쿼리를 생성한다는 것입니다. 옵션 2는 개체 A가 많은 자식을 포함 할 때 오랜 시간이 걸릴 수 있으며 옵션 2는 단일 SQL 쿼리 만 생성 한 다음 계속 이동합니다 행복하게. 이 문제와 관련하여 "모범 사례"가 있습니까?

답변

6

을하는 데 도움이 귀하의 기록을 삭제할 수 있습니다 정보

  • 을 반영 둘 다 @CascadeOnDelete 주석을 사용하는 경우. 또한 EclipseLink는 캐스케이드 DDL을 생성합니다. 이 데이터베이스를 시켜서 삭제를 최적화 http://wiki.eclipse.org/EclipseLink/Examples/JPA/DeleteCascade

    참조는, 그것을 할뿐만 아니라 개체를 제거하여 캐시와 퍼시스턴스 유닛을 유지합니다.

    orphanRemoval = true는 데이터베이스 캐스케이드 제약 조건이 처리하지 않는 컬렉션에서 제거 된 개체도 삭제하므로 JPA에 규칙이 여전히 필요하다는 점에 유의하십시오. 또한 데이터베이스가 제약 조건의 역방향으로 만 계단식으로 연결할 수 있거나 외래 키가있는 OneToOne 또는 조인 테이블이있는 OneToMany를 데이터베이스에서 계단식으로 연결할 수 없기 때문에 데이터베이스에서 삭제를 처리 할 수없는 관계가 있습니다.

  • +0

    내가 찾고있는 것 같습니다! 벤더에 따라 다르긴하지만 그렇게해야 할 것입니다. 감사! –

    3

    데이터베이스를 선호합니다. 왜?

    • 데이터베이스는이
    • 데이터베이스를 수행하는 무결성 및 관계 정보를 보유 할 수있는 주요 장소이어야한다 훨씬 빨리 아마. 당신이 (JPA없이 예) 다른 응용 프로그램/플랫폼에 연결하는 경우 JPA는, 당신은 여전히 ​​cascadingly 사용할 수는 EclipseLink에서 증가 데이터 무결성
    +0

    본인의 의견에 동의하지만 엔티티 관리자에게 여러 개체가 삭제되었다는 알림을받지 않아야합니까? 어쩌면 최악의 시나리오는 몇 분 동안 일부 죽은 개체가 캐싱된다는 것입니다 (그러나 일반적으로 액세스 할 수없는 것은 제거되는 부모 개체를 통과하기 때문입니다). JPA뿐만 아니라 데이터베이스에서도 계단식을 지정하면 2 점과 3 점을 무시할 수 있습니다. 이 옵션에 대해 어떻게 생각하십니까? –

    +1

    당신 말이 맞아요. 미안하지만, 저는 당신의 질문을 철저히 읽지 않았습니다. 나는 이것이 JPA 구현에 달려 있다고 생각한다. 데이터베이스와 JPA 주석이 달린 클래스 모두에서 계단식 삭제를 지정할 수 있습니다. 좋은 구현은 캐시를 새로 고침하여이를 반영해야합니다. 하지만 JPA를 사용했던 지난 번 (절전 모드로 꽤 오래 전), 이것은 분명히 사실이 아니 었습니다. 해결책은 모든 캐싱을 비활성화하는 것입니다 ... –

    0

    This answer은 데이터베이스가 아닌 계단식을 처리하는 JPA가되어야하는 이유에 대한 몇 가지 중요한 주장을 제기합니다. 당신은 어떤 상황 오류를 얻을 수에 데이터베이스에 폭포를 만들고, (성능 문제에 대한) 최대 절전 모드에서 그들을 선언하지 않는다면 ...

    :

    여기에 관련 견적입니다. 이것은 Hibernate가 자신의 세션에 캐시에 엔티티를 저장하기 때문에, 캐스케이드에서 데이터베이스 삭제에 대해 알지 못하기 때문입니다.

    당신이 두 번째 레벨 캐시를 사용하면 이 캐시는 한 이전 값이 캐시에 저장되어 다른 세션에 보이지 않는 것 이상 세션 DB 측에 이러한 변화보다는 살고 있기 때문에, 상황은 더 악화입니다 .