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 where 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);
To delete a record from database, EntityManager interface provides remove() method. The remove() method uses primary key to delete the particular record.
You can prevent that by calling the flush method on the EntityManager. After you've done that, you can remove a specific entity from the persistence context by calling the detach method or you can call the clear method to clear the persistence context completely.
Clearing the entity manager empties its associated cache, forcing new database queries to be executed later in the transaction. It's almost never necessary to clear the entity manager when using a transaction-bound entity manager.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With