2010-05-17 38 views
7

Khi tôi cố gắng thực hiện một thực thểManager.remove (ví dụ) nhà cung cấp JPA cơ bản ban hành một hoạt động xóa riêng biệt trên mỗi thực thể GroupUser. Tôi cảm thấy điều này là không đúng từ một quan điểm hiệu suất, vì nếu một nhóm có 1000 người dùng sẽ có 1001 cuộc gọi được ban hành để xóa toàn bộ nhóm và thực thể nhóm nhóm itr.JPA thực thể loại bỏ hoạt động không thực hiện

Sẽ có ý nghĩa hơn khi viết truy vấn được đặt tên để xóa tất cả các mục nhập trong bảng nhóm người dùng (ví dụ: xóa khỏi group_user trong đó group_id =?), Vì vậy tôi chỉ phải thực hiện 2 cuộc gọi để xóa nhóm.

@Entity 
@Table(name = "tbl_group") 

public class Group { 

    @OneToMany(mappedBy = "group", cascade = CascadeType.ALL, fetch = FetchType.LAZY) 
    @Cascade(value = DELETE_ORPHAN) 
    private Set<GroupUser> groupUsers = new HashSet<GroupUser>(0); 

Trả lời

8

Câu trả lời đơn giản là có. Nếu bạn muốn xóa Group và bạn biết có rất nhiều bản ghi trong bảng GroupUser, thì tốt hơn hết là tạo truy vấn xóa sẽ thực hiện tất cả trong một lô thay vì một và một.

Nếu bạn không có tầng trên cơ sở dữ liệu cơ bản, (hoặc thậm chí nếu bạn làm) thực hành tốt của nó để làm điều đó theo đúng thứ tự.

Vì vậy, hãy xóa GroupUser trước tiên.
Giả sử bạn có đối tượng Nhóm bạn muốn xóa.

int numberDeleted = entityManager.createQuery("DELETE FROM GroupUser gu WHERE gu.group.id=:id").setParameter("id",group.getId()).executeUpdate(); 

Quay trở lại hiển thị số lượng bản ghi đã bị xóa.

Bây giờ bạn đã có thể xóa Group

entityManager.remove(group); 
entityManager.flush(); 

CẬP NHẬT

Có vẻ như @OnDelete trên @OneToMany hiện các trick

+0

Kỳ lạ của nó là tôi không thể dựa vào tùy chọn cascade = DELETE theo thông số JPA, vì nó xóa tất cả các cá thể GroupUser 1-by-1. Điều này ngụ ý rằng tôi phải viết mã tùy chỉnh để tối ưu hóa việc xóa các mục nhập. – Sam

+2

@Samuel. Tôi đã hỏi một câu hỏi rất giống ngày hôm trước. Bạn có thể tìm thấy nó ở đây: http://stackoverflow.com/questions/2856460/hibernate-doesnt-generate-cascade Và mẹo để sử dụng @OnDelete thay vì thác có thể có nghĩa là nó không xóa trường hợp 1 của 1 Bạn có thể thử. Tôi chưa thử nó. –

+0

@Shervin - @OnDelete hoạt động như một sự quyến rũ, bằng cách nào đó đã bỏ lỡ bằng cách sử dụng nó. Tôi khuyên bạn nên thêm hỗ trợ cho điều này cũng cho tất cả các chú thích @OneToMany. – Sam

2

Kể từ khi GroupUser có thác là tốt, tôi không nghĩ rằng có một cách để nói với ngủ đông đến hàng loạt xóa chúng thông qua cấu hình.

Nhưng nếu bạn chắc chắn không có cascade=DELETE trên GroupUser, cảm thấy tự do để phát hành một HQL/JPA-QL truy vấn:

DELETE FROM GroupUser WHERE group=:group 

Nếu có thác, xử lý chúng với một truy vấn là tốt.

+0

GroupUser không có bất kỳ mục cascadable. Điều kỳ lạ là tôi không thể dựa vào tùy chọn tầng = DELETE theo thông số JPA, vì nhà cung cấp ORM cơ bản xóa tất cả các cá thể GroupUser 1-by-1. Điều này ngụ ý rằng tôi phải viết mã tùy chỉnh để tối ưu hóa việc xóa các mục nhập. – Sam

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