2009-08-20 36 views
25

Tôi nhận thấy rằng các hồ sơ mồ côi không bị xóa khi xóa khỏi bộ sưu tập trong Hibernate. Tôi phải làm gì đó sai đơn giản, (đây là Hibernate-101!), Nhưng tôi không thể tìm thấy nó ..Hibernate xóa trẻ mồ côi khi cập nhật bộ sưu tập

Do sau:

public class Book { 
    @ManyToOne 
    @NotNull 
    Author author; 
} 
public class Author 
{ 
    @OneToMany(cascade={CascadeType.ALL}) 
    List<Book> books; 
} 

Và mã cập nhật sau:

Author author = authorDAO.get(1); 
Book book = author.getBooks().get(0); 
author.getBooks().remove(0); 
authorDAO.update(author); 

AuthorDAO đoạn mã:

@Override 
public void update(T entity) { 
    getSession().update(entity); 
} 

các bài kiểm tra sau thất bại:

0.123.
Author author = author.get(1); 
assertEquals(0,author.getBooks().size()); // Passes 
Book dbBook = bookDAO.get(book.getId()) 
assertNull(dbBook); // Fail! dbBook still exists! 
assertFalse(author.getBooks().contains(dbBook) // Passes! 

Nói tóm lại, tôi đang tìm kiếm:

  • Trong khi cuốn sách được lấy ra từ bộ sưu tập của Tác giả của cuốn sách, nó vẫn tồn tại trong cơ sở dữ liệu
  • Nếu tôi kiểm tra book.getAuthor().getBooks(), cuốn sách không tồn tại trong bộ sưu tập đó

Điều này "cảm thấy" như tôi không xả phiên hoặc buộc cập nhật một cách thích hợp - nhưng tôi không chắc mình nên làm điều đó ở đâu. Cùng tĩnh mạch đó, điểm khác có thể ảnh hưởng:

  • Tôi đang thực hiện ở trên trong một bài kiểm tra JUnit trang trí với @RunWith(SpringJUnit4ClassRunner.class)
  • tôi ban đầu trúng vấn đề này bên trong một thói quen cập nhật được trang trí với @Transactional, tuy nhiên, Tôi đã tái tạo nó trong một thử nghiệm JUnit cũ.

Bất kỳ lời khuyên nào sẽ được đánh giá rất nhiều!

EDIT: Cảm ơn tất cả các phản hồi đã có. Hơn nữa để bình luận dưới đây, tôi đã thêm @Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN) để phụ huynh, do đó, nó bây giờ:

public class Author 
{ 
    @OneToMany(cascade={CascadeType.ALL}) 
    @Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN) 
    List<Book> books; 
} 

Tôi vẫn đang tìm kiếm các kết quả tương tự. Tôi PHẢI mất một cái gì đó đơn giản.

Trả lời

16

Bạn không làm gì sai. Bạn chỉ không loại bỏ thực thể con. Bạn có thể làm điều này với một xoá rõ ràng() của thực thể con (ngoài những gì bạn đang làm) hoặc sử dụng chú thích đó gây ra các bản ghi trẻ mồ côi sẽ bị xóa.

Ngoài ra, điều đáng nói đến là CascadeType.DELETE cũng sẽ không xóa trẻ mồ côi. Điều đó có nghĩa là cái gì khác. Xem JPA CascadeType.ALL does not delete orphans.

Về cơ bản để làm điều này tự động bạn sẽ muốn điều này trên bộ sưu tập trong các phụ huynh:

org.hibernate.annotations.CascadeType.DELETE_ORPHAN 
+0

Tôi đã thêm chú thích này nhưng chú thích vẫn không hoạt động - kết quả giống như trước đây. –

+2

Bạn cũng có thể đặt tham chiếu tác giả trong sách thành không? – cletus

+0

Không, tôi nghĩ đó là điểm chú thích DELETE_OPRHAN? –

0

Hãy thử sử dụng annoation sau đây nếu bạn muốn 'bắc cầu phụ thuộc' behavour.

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

3

Tùy chọn cascade trong @OneToMany chú thích là một mảng, những gì bạn muốn là:

@OneToMany(cascade={CascadeType.ALL, CascadeType.DELETE_ORPHAN}) 
0

xin vui lòng thêm @onDelete có lẽ tác phẩm này với bạn

public class Author 
{ 
    @OneToMany(cascade={CascadeType.ALL}) 
    @OnDelete(action = OnDeleteAction.CASCADE) 
    @Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN) 
    List<Book> books; 
} 
+0

Xin chào. Điều này cũng không có hiệu lực. –

+0

Bạn có cam kết phiên của bạn hoặc xóa phiên sau khi xóa? – Am1rr3zA

0

Hình như bạn có thể thiếu chú thích mappedBy. Hãy thử:

public class Book { 
    @ManyToOne 
    @NotNull 
    Author author; 
} 
public class Author { 
    @OneToMany(mappedBy="author", cascade={CascadeType.ALL}) 
    List<Book> books; 
} 
35

cho những người đang tìm kiếm giải pháp của họ: Bây giờ trong Hibernate, resp. JPA 2.0, đây là cách đúng:

@OneToMany(orphanRemoval=true) 
Các vấn đề liên quan