2010-05-17 66 views
7

當我嘗試執行entityManager.remove(實例)時,底層JPA提供程序會在每個GroupUser實體上發出單獨的刪除操作。我覺得從性能角度來看這是不正確的,因爲如果一個組有1000個用戶,將會有1001個呼叫發出來刪除整個組和itr groupuser實體。JPA entitymanager刪除操作性能不高

編寫一個命名查詢以刪除groupuser表中的所有條目(例如,從group_user中刪除group_id =?)是否更有意義,因此我必須只進行2次調用來刪除組。

@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); 

回答

8

簡單的答案是肯定的。 如果您想要刪除Group,並且您知道GroupUser表中有大量記錄,那麼創建刪除查詢會更好,它可以在一個批處理中執行所有操作,而不是一個和一個。

如果您在底層數據庫上沒有級聯(或者即使您這樣做),它的良好做法是按照正確的順序進行。

所以先刪除GroupUser
假設您有要刪除的組對象。

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

返回的int顯示刪除的記錄數。

現在你終於可以刪除Group

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

UPDATE

好像@OnDelete@OneToMany的伎倆

+0

奇怪的是,我無法依據JPA規範依賴級聯= DELETE選項,因爲它會一次一個地刪除所有GroupUser實例。 這意味着我必須編寫自定義代碼來優化條目的刪除。 – Sam 2010-05-19 17:50:22

+2

@Samuel。我前幾天也問過一個非常類似的問題。 你可以在這裏找到它:http://stackoverflow.com/questions/2856460/hibernate-doesnt-generate-cascade 而使用@OnDelete而不是級聯的提示可能意味着它不會刪除實例1 1你可以試試看。儘管如此,我還沒有嘗試過。 – 2010-05-19 20:09:05

+0

@Shervin - @OnDelete就像一個魅力,不知何故錯過了它。我建議你爲所有@OneToMany註解添加對此的支持。 – Sam 2010-05-21 04:34:06

2

由於GroupUser可能有瀑布,以及,我不認爲有一種方法來告訴Hibernate通過配置批量刪除它們。

但如果你一定有上GroupUser沒有cascade=DELETE,隨意發出HQL/JPA-QL查詢:

DELETE FROM GroupUser WHERE group=:group 

如果有瀑布,處理他們的查詢,以及。

+0

GroupUser沒有任何級聯的條目。 奇怪的是,我不能依賴JPA規範中的cascade = DELETE選項,因爲底層ORM提供程序會一個一個刪除所有GroupUser實例。 這意味着我必須編寫自定義代碼來優化條目的刪除。 – Sam 2010-05-19 17:51:09