2010-05-17 103 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