user3123690
user3123690

Reputation: 1241

Best strategy to delete a large entity in Hibernate

I have a parent Entity which has many chilren collection in a web application. What is the best stratety deleting this entity? I could just delete the parent and all children collection will be deleted as a result because of cascade. But I am afraid this would take long time and might cause table locking which will affect other users. Or I can remove each children and remove the parent entity at the end. What is the best way? To remove both parent and children at once. I use this.

entityManger.remove(parent);  -> one transaction

Or I can loop through each children collection and remove all children first and at the end remove the parent. This would split one large transaction into many smaller ones.

Upvotes: 2

Views: 5048

Answers (3)

Joshua H
Joshua H

Reputation: 774

All the other answers doesn't seem to address your problem.

First of all, unless you are dealing with heavily used table or deletion in order or millions, you are not going to face any significant performance issue.

However, if you do have the above scenario, you can do several things (and you must choose between performance or ROW locking prevention)

1) Make sure your foreign key has index in it

2) Do a batch delete like you said. This will prevent locking but will slow the performance since the app needs to call several statements to DB. More info here https://vladmihalcea.com/how-to-batch-delete-statements-with-hibernate/

3) Use native SQL queries and do a batch delete

DECLARE @RowCount int
WHILE 1=1
    BEGIN
        DELETE TOP (10000) t1
        FROM table t1
        WHERE t1.FK_ID = yourFkId

        SET @RowCount = @@ROWCOUNT

        IF (@RowCount < 10000) BREAK
    END

The most important thing is to test whether it is your bottleneck issue and avoid premature optimization.

Hope it helps

Upvotes: 1

0gam
0gam

Reputation: 1423

@OneToMany default strategy fetch = FetchType.LAZY

cascadeType in ALL, PERSIST, MERGE, REMOVE, REFRESH, DETACH.

if you want to delete parent with children collection. you change Parent cascade = {cascadeType.REMOVE and ALL}

You don`t define cascadeType.REMOVE. take error(db-fk-key-constraint violated)

@Entity
public class Company {

    @OneToMany(mappedBy = "company", cascade = { CascadeType.REMOVE })
    private List<ExhibitionGroup> exhibitionGroup;

    ...
}

@Entity
public class ExhibitionGroup {

    @ManyToOne
    @JoinColumn(name = "company_id")
    private Company company;

    ...
}

or using

  @OneToMany(mappedBy = "company", orphanRemoval = ture)

Orphan Removal in Relationships When a target entity in one-to-one or one-to-many relationship is removed from the relationship, it is often desirable to cascade the remove operation to the target entity. Such target entities are considered “orphans,” and the orphanRemoval attribute can be used to specify that orphaned entities should be removed. For example, if an order has many line items and one of them is removed from the order, the removed line item is considered an orphan. If orphanRemoval is set to true, the line item entity will be deleted when the line item is removed from the order.

The orphanRemoval attribute in @OneToMany and @oneToOne takes a Boolean value and is by default false.

The following example will cascade the remove operation to the orphaned customer entity when it is removed from the relationship:

@OneToMany(mappedBy="customer", orphanRemoval="true")
public List<Order> getOrders() { ... }

Upvotes: 1

sixtytrees
sixtytrees

Reputation: 1233

You can only do it if parent has no children. You will have to first delete all children before you deal with the parent.

Upvotes: 1

Related Questions