JPA CascadeType.ALL không xóa trẻ mồ côi


132

Tôi gặp sự cố khi xóa các nút mồ côi bằng JPA với ánh xạ sau

@OneToMany (cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "owner")
private List<Bikes> bikes;

Tôi đang gặp vấn đề về vai trò mồ côi treo trên cơ sở dữ liệu.

Tôi có thể sử dụng thẻ chú thích org.hibernate.annotations.CascadeHibernate cụ thể nhưng rõ ràng tôi không muốn gắn giải pháp của mình vào triển khai Hibernate.

EDIT : Có vẻ như JPA 2.0 sẽ bao gồm hỗ trợ cho việc này.

Câu trả lời:


164

Nếu bạn đang sử dụng nó với Hibernate, bạn sẽ phải xác định rõ ràng chú thích CascadeType.DELETE_ORPHAN, có thể được sử dụng cùng với JPA CascadeType.ALL.

Nếu bạn không có kế hoạch sử dụng Hibernate, trước tiên bạn sẽ phải xóa các phần tử con một cách rõ ràng và sau đó xóa bản ghi chính để tránh mọi bản ghi mồ côi.

trình tự thực hiện

  1. lấy hàng chính bị xóa
  2. lấy các phần tử con
  3. xóa tất cả các phần tử con
  4. xóa hàng chính
  5. phiên họp kín

Với JPA 2.0, giờ đây bạn có thể sử dụng tùy chọn orphanRemoval = true

@OneToMany(mappedBy="foo", orphanRemoval=true)

3
cảm ơn tôi cuối cùng đã đi theo con đường này, tôi nghĩ rằng đây là một chút quá mức cho thông số JPA.
Paul Whelan

13
Tiêu chuẩn JPA 2.0 hiện có xóaOrphan như một thuộc tính của @OneToMany Nếu bạn đang sử dụng chế độ ngủ đông mới nhất, bạn có thể thực hiện @OneToMany (..., xóaOrphan = true)
jomohke

Trình tự thực hiện khi tôi chỉ cập nhật các phần tử con là gì? hồ sơ mồ côi sẽ bị xóa?
jAckOdE

113

Nếu bạn đang sử dụng JPA 2.0, bây giờ bạn có thể sử dụng orphanRemoval=truethuộc tính của @xxxToManychú thích để loại bỏ trẻ mồ côi.

Trên thực tế, CascadeType.DELETE_ORPHANđã bị phản đối trong 3.5.2-Final.


6
Trên thực tế tôi nghĩ orphanRemoval = true có nghĩa là một cái gì đó khác, tức là xóa một đối tượng khi tôi xóa nó khỏi bộ sưu tập của cha mẹ. Xem download.oracle.com/javaee/6/tutorial/doc/bnbqa.html#giqxy
Archie

Vui lòng g thông qua liên kết của Archie.
Jigar Shah

4
orphanRemoval = true cũng không hoạt động. Nó phải được thực hiện theo cách cũ.
Joe Almore

45
╔═════════════╦═════════════════════╦═════════════════════╗
   Action      orphanRemoval=true    CascadeType.ALL   
╠═════════════╬═════════════════════╬═════════════════════╣
   delete         deletes parent      deletes parent   
   parent         and orphans         and orphans      
╠═════════════╬═════════════════════╬═════════════════════╣
   change                                              
  children      deletes orphans         nothing        
    list                                               
╚═════════════╩═════════════════════╩═════════════════════╝

1
Điều gì xảy ra nếu tôi có cascade = CascadeType.ALL, orphanRemoval = falsevà xóa cha mẹ? Nó sẽ xóa trẻ em, mặc dù tôi đặc biệt nói KHÔNG?
izogfif


7

bạn có thể sử dụng @PrivateOwned để xóa trẻ mồ côi, ví dụ:

@OneToMany(mappedBy = "masterData", cascade = {
        CascadeType.ALL })
@PrivateOwned
private List<Data> dataList;

5
Cảm ơn @reshma cần lưu ý @PrivateOwned là một phần mở rộng JPA eclipselink.
Paul Whelan

5

Tôi chỉ tìm giải pháp này nhưng trong trường hợp của tôi nó không hoạt động:

@OneToMany(cascade = CascadeType.ALL, targetEntity = MyClass.class, mappedBy = "xxx", fetch = FetchType.LAZY, orphanRemoval = true) 

orphanRemoval = true không có tác dụng.


1
Tôi cần phải làm sạch và xây dựng trước khi thay đổi có hiệu lực.
maralbjo

Ồ, tôi đã tìm kiếm một giờ về lý do tại sao việc thêm CascadeType.ALL trên ManyToOne của tôi không phải là xóa tầng. Làm sạch và xây dựng và nó hoạt động. Cảm ơn @maralbjo.
Andrew Mairose


2

Tôi có cùng một vấn đề và tôi tự hỏi tại sao điều kiện dưới đây không xóa được trẻ mồ côi. Danh sách các món ăn không bị xóa trong Hibernate (5.0.3.Final) khi tôi thực hiện truy vấn xóa có tên:

@OneToMany(mappedBy = "menuPlan", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Dish> dishes = new ArrayList<>();

Sau đó, tôi nhớ rằng tôi không được sử dụng truy vấn xóa có tên , mà là EntityManager. Khi tôi sử dụng EntityManager.find(...)phương thức để tìm nạp thực thể và sau đó EntityManager.remove(...)xóa nó, các món ăn cũng bị xóa.


2

Chỉ cần @OneToMany(cascade = CascadeType.ALL, mappedBy = "xxx", fetch = FetchType.LAZY, orphanRemoval = true).

Xóa targetEntity = MyClass. Class , nó hoạt động rất tốt.


1

Đối với các bản ghi, trong OpenJPA trước JPA2, đó là @EuityDepguard.


0

Tôi đã sử dụng ánh xạ một đến một, nhưng đứa trẻ không bị xóa JPA đã vi phạm khóa ngoại

Sau khi sử dụng orphanRemoval = true, sự cố đã được giải quyết


@OneToOne (cascade = CascadeType.ALL, orphanRemoval = true) @JoinColumn (name = "CHILD_OID") con riêng;
vipin chauhan
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.