2008-11-20 33 views
116

tôi đang gặp khó khăn xóa nút mồ côi sử dụng JPA với các bản đồ sauJPA CascadeType.ALL không xóa trẻ mồ côi

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

Tôi gặp vấn đề trong những vai trò mồ côi treo xung quanh cơ sở dữ liệu.

Tôi có thể sử dụng chú thích org.hibernate.annotations.Cascade Thẻ cụ thể Hibernate nhưng rõ ràng là tôi không muốn kết hợp 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.

Trả lời

138

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 kết hợp với JPA CascadeType.ALL.

Nếu bạn không định sử dụng Hibernate, trước tiên bạn phải xóa phần tử con và xóa bản ghi chính để tránh bất kỳ bản ghi trẻ mồ côi nào.

thực hiện chuỗi

  1. lấy hàng chính được xóa
  2. yếu tố con lấy
  3. xóa tất cả các phần tử con
  4. xóa hàng chính
  5. phiên gần

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

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

nhờ tôi đã kết thúc đi tuyến đường này, tôi nghĩ đây là một chút của một oversite cho spec JPA. –

+12

Chuẩn JPA 2.0 hiện đã xóaOrphan thành thuộc tính thành @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 (..., deleteOrphan = true) – jomohke

+0

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

104

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

Thực ra, CascadeType.DELETE_ORPHAN không được dùng nữa trong phiên bản 3.5.2.

+3

+1 để cung cấp câu trả lời nâng cao cho câu hỏi này! –

+5

Thực ra tôi nghĩ orphanRemoval = true 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 http://download.oracle.com/javaee/6/tutorial/doc/bnbqa.html#giqxy – Archie

+3

nó không hoạt động với @ManyToMany như tôi biết. – ses

4

Tôi chỉ tìm thấy 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

Bạn đang sử dụng JPA2? –

+1

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

+0

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

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, nó là @ElementDependant.

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; 
+4

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

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

Câu trả lời khủng khiếp ... Không giải thích gì, chỉ cần nuốt một bảng ... -.- –

+0

Điều gì sẽ xảy ra nếu tôi có 'cascade = CascadeType.ALL, orphanRemoval = false' và xóa phụ huynh? Nó sẽ xóa trẻ em, mặc dù tôi đã nói cụ thể KHÔNG? – izogfif

2

tôi đã cùng một vấn đề và tôi tự hỏi tại sao tình trạng này dưới đây không xóa các trẻ em 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 một truy vấn xóa 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 phải sử dụng một truy vấn xóa tên, nhưng EntityManager. Khi tôi đã sử dụng phương thức EntityManager.find(...) để tìm nạp đối tượng và sau đó EntityManager.remove(...) để xóa nó, các món ăn cũng đã bị xóa.

0

Tôi đã sử dụng 1-1 lập bản đồ, nhưng con đã không bị xóa JPA đã được đưa ra chìa khóa vi phạm ngoại

Sau khi sử dụng orphanRemoval = true, vấn đề đã được giải quyết

+0

@OneToOne (cascade = CascadeType.ALL, orphanRemoval = true) @JoinColumn (name = "CHILD_OID") riêng Con trẻ; –

Các vấn đề liên quan