2011-08-25 2 views
63

다음과 같은 단방향@ManyToOne 관계가 있다고 가정 해 보겠습니다.JPA : 단방향 다 대일 및 연쇄 적 삭제

@Entity 
public class Parent implements Serializable { 

    @Id 
    @GeneratedValue 
    private long id; 
} 

@Entity 
public class Child implements Serializable { 

    @Id 
    @GeneratedValue 
    private long id; 

    @ManyToOne 
    @JoinColumn 
    private Parent parent; 
} 
부모 P와 자식 C 1 ... C n를 P로 다시 참조하면 깨끗하고 JAX에서 아이들을 자동으로 제거하는 예쁜 방법 C 1 ... C n, P가 제거되면 (즉, entityManager.remove(P))?

내가 찾고있는 기능은 SQL에서 ON DELETE CASCADE과 비슷한 기능입니다.

+1

'Child'에만 'Parent'에 대한 참조가있는 경우 (참조가 단방향 임) 'Child'목록에 '@OneToMany'매핑을 추가하고 'Cascade = ALL '속성을'부모 '에게 보냅니 까? 나는 JPA가 단지 1 면만이 참조를 보유한다는 것을 해결해야한다고 생각한다. – kvDennis

+1

@kvDennis, 많은면을 한면에 단단히 묶고 싶지 않은 경우가 있습니다. 예 : 보안 사용 권한이 투명한 ACL과 유사한 설정에서 "추가 기능" – Bachi

답변

56

부모와 자식을 양방향으로 연결하지 않는 한 JPA의 관계는 항상 단방향입니다. 부모로부터 자식에게 REMOVE 연산을 계단식으로 연결하려면 부모로부터 자식까지의 관계가 필요합니다.

그러므로 당신은이 작업을 수행해야합니다 :

  • 중 하나는, @ManyToOne 양방향 또는 단방향 @OneToMany에 단방향 @ManyToOne 관계를 변경합니다. 그런 다음 EntityManager.remove이 부모와 자식을 제거하도록 REMOVE 작업을 계단식으로 처리 할 수 ​​있습니다. orphanRemoval을 true로 지정하여 상위 콜렉션의 하위 엔티티가 null로 설정된 경우, 즉 상위 콜렉션에 존재하지 않을 때 하위를 제거하면 분리 된 하위를 삭제할 수 있습니다.
  • 또는 자식 테이블의 외래 키 제약 조건을 ON DELETE CASCADE으로 지정하십시오. 영속 컨텍스트를 새로 고쳐야하기 때문에 EntityManager.remove(parent)을 호출 한 후 EntityManager.clear()을 호출해야합니다. 하위 엔티티는 데이터베이스에서 삭제 된 후에도 지속성 컨텍스트에 존재하지 않아야합니다.
+4

은 JPA 주석으로 No2를 수행하는 방법입니까? – user2573153

+2

Hibernate xml 매핑을 사용하여 No2를 수행하는 방법은 무엇입니까? – arg20

+0

아래 답변은 당신보다 낫다. – Enerccio

11

는 다음과 같이 양방향 관계를 만듭니다

@Entity 
public class Parent implements Serializable { 

    @Id 
    @GeneratedValue 
    private long id; 

    @OneToMany(mappedBy = "parent", cascade = CascadeType.REMOVE) 
    private Set<Child> children; 
} 
+0

큰 아이 세트를 조작하는 데 엄청난 양의 시간이 걸리기 때문에 JPA에서는 양방향 관계가 끔찍하다. – Enerccio

-1

@Cascade (org.hibernate.annotations.CascadeType.DELETE_ORPHAN을)를

을 감안할 때 주석이 날 위해 일했습니다. 예를 들어

: -

 public class Parent{ 
      @Id 
      @GeneratedValue(strategy=GenerationType.AUTO) 
      @Column(name="cct_id") 
      private Integer cct_id; 
      @OneToMany(cascade=CascadeType.REMOVE, fetch=FetchType.EAGER,mappedBy="clinicalCareTeam", orphanRemoval=true) 
      @Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN) 
      private List<Child> childs; 
     } 
      public class Child{ 
      @ManyToOne(fetch=FetchType.EAGER) 
      @JoinColumn(name="cct_id") 
      private Parent parent; 
    } 
39

당신이 주석 @OnDelete를 사용하여 JPA 공급자로 최대 절전 모드를 사용하는 경우. 이 주석은 트리거에 ON DELETE CASCADE 트리거를 추가하여 하위 항목 삭제를 데이터베이스에 위임합니다.

예 : 부모 아이에서 단방향 관계가 자동으로 모든 아동을 제거하기에 충분이 솔루션을

public class Parent { 

     @Id 
     private long id; 

} 


public class Child { 

     @Id 
     private long id; 

     @ManyToOne 
     @OnDelete(action = OnDeleteAction.CASCADE) 
     private Parent parent; 
} 

. 이 솔루션은 청취자 등을 필요로하지 않습니다. 부모로부터 DELETE와 같은 질의는 id = 1으로 어린이를 제거합니다.

+0

@ManyToOne 디자인을 변경하지 않고도 완벽한 솔루션이다. –

+0

이것은 대단한 대답입니다. 그것은 전체적으로 중요한 기능입니다. – Yoi

+2

이 방법으로는 작동하지 않을 수 있습니다. 특정 버전의 최대 절전 모드 나 이와 같은 더 자세한 예제가 있습니까? – Mardari

관련 문제