JPA entitymanager remove operation is not performant
When I try to do an entityManager.remove(instance) the underlying JPA provider issues a separate delete operation on each of the GroupUser entity. I feel this is not right from a performance perspective, since if a Group has 1000 users there will be 1001 calls issued to delete the entire group and itr groupuser entity.
Would it make more sense to write a named query to remove all entries in groupuser table (e.g. delete from group_user whe开发者_如何学编程re group_id=?), so I would have to make just 2 calls to delete the group.
@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);
Simple answer is yes.
If you want to delete a Group
and you know there are tons of records in GroupUser
table, then it is much better to create a delete query that will do all in one batch instead of one and one.
If you have no cascading on the underlying database, (or even if you do) its good practice to do it in correct order.
So delete the GroupUser
first.
Assuming you have a the Group object you want to delete.
int numberDeleted = entityManager.createQuery("DELETE FROM GroupUser gu WHERE gu.group.id=:id").setParameter("id",group.getId()).executeUpdate();
The returning int shows how many records where deleted.
Now you can finally delete Group
entityManager.remove(group);
entityManager.flush();
UPDATE
Seems like @OnDelete
on the @OneToMany
does the trick
Since the GroupUser
may have cascades as well, I don't think there is a way to tell hibernate to batch-delete them via configuration.
But if you are certain there are no cascade=DELETE
on GroupUser
, feel free to issue an HQL/JPA-QL query:
DELETE FROM GroupUser WHERE group=:group
If there are cascades, handle them with a query as well.
精彩评论