2009-04-16 30 views
17

Một vấn đề mà tôi thường phải đối mặt với Hibernate là có một danh sách (gọi nó là listA) của các đối tượng mà tôi muốn tồn tại đối với một thực thể (myEntity) nhưng trước tiên phải so sánh chúng với danh sách hiện có trên thực thể và xóa các danh sách không có trong danh sáchA. Cách đơn giản để thực hiện điều này là xóa danh sách trên thực thể và chỉ cần thêm tất cả danh sáchA vào thực thể, tuy nhiên tôi thường phải thực hiện một số xác nhận trên các phần tử trước khi chúng bị xóa - ví dụ:. để kiểm tra xem người dùng này có được phép xóa chúng hay không.Hibernate: Cách tốt nhất để xóa các phần tử trong bộ sưu tập

cách tiếp cận hiện tại của tôi cảm thấy lúng túng:

//Delete the elements that have been removed 
//Use toArray to avoid ConcurrentModificationException 
for(ObjectA a : myEntity.getObjectAList().toArray(new ObjectA[myEntity.getObjectAList().size()])) { 
    if(!listA.contains(a)) { 

     //Check if this element can be deleted 
     if(canDelete(a)) { 
      entityManager.remove(a); 
      myEntity.getObjectAList().remove(a); 
     } 
    } 
} 

//Add the elements that don't already exist 
for(ObjectA a : listA) { 
    if(!myEntity.getObjectAList().contains(a)) { 
     myEntity.getObjectAList().add(a); 
    } 
} 

Bất cứ phòng nào để cải thiện?

Cảm ơn.

Trả lời

10

Hãy thử sử dụng:

myEntity.getObjectAList().removeAll(listA); 

này sẽ chỉ giữ các đối tượng mà không phải là đã có trong Lista.

Ngoài ra, nếu bạn cần phải làm điều gì đó như thế này bằng tay trong tương lai, sử dụng một iterator:

Iterator<?> it = myEntitiy.getObjectAList().iterator(); 
while (it.hasNext()) 
{ 
    ... 
} 

Sau đó it.next() sẽ cung cấp cho bạn các mục tiếp theo trong mảng, và it.remove() sẽ loại bỏ giá trị cuối cùng của() tiếp theo cho bạn, mà không đưa ra một ngoại lệ nếu bạn giữ vòng lặp.

Nếu bạn cũng cần có khả năng thêm giá trị mới trong khi lặp, hãy cân nhắc sử dụng listIterator() để thay thế.

+0

Tôi không thể sử dụng removeAll() vì tôi cần thực hiện một số xác thực đối với các thành phần riêng lẻ trước xóa chúng. Cảm ơn bạn đã sử dụng mẹo Iterator. – Damo

+2

Tôi nghĩ rằng điểm của removeAll là nó sẽ cắt danh sách trên đối tượng của bạn xuống những người bạn cần phải kiểm tra để xóa. Sau đó, bạn kiểm tra tất cả những thứ đó và xóa nếu được phép. Sau đó, bạn có thể thêm tất cả listA mà không kiểm tra xem chúng đã có sẵn chưa bởi vì bạn đã xóa chúng. – digitaljoel

16

Tôi biết câu hỏi này là khá cũ, nhưng tôi chạy trong cùng một vấn đề và tôi nghĩ rằng câu trả lời được đưa ra là không đủ. Vì vậy, bạn có thể đạt được kết quả chính xác mà bạn muốn chỉ thêm thuộc tính "orphanRemoval=true" để bạn ánh xạ chú thích. Việc loại bỏ trẻ mồ côi hoạt động theo cách này (như được mô tả trong trang 136 của cuốn sách "Bắt đầu Nền tảng Java EE 6 với GlassFish 3":

"[...] mã sẽ tự động xóa thực thể Địa chỉ khi khách hàng bị xóa, hoặc khi mối quan hệ bị hỏng (bằng cách thiết lập để null thuộc tính địa chỉ hoặc bằng cách xóa thực thể con khỏi bộ sưu tập trong trường hợp một-nhiều) ".

Đó là, nếu bạn xóa một mục khỏi bộ sưu tập được ánh xạ với loại bỏ mồ côi và sau đó hợp nhất đối tượng, mục này cũng sẽ bị xóa.

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