Alf
Alf

Reputation: 2321

Hibernate does not add 'on delete cascade'

Using cascade = CascadeType.REMOVE hibernate does not add 'ON DELETE CASCADE' during table generation. Is this the right behavior? No problem if I perform em.remove() on parent object but an error raises when I try to execute bulk deletion via HQL.

PostgreSQL 9.1, Hibernate 4.0.0.CR7

Upvotes: 1

Views: 5651

Answers (3)

tscho
tscho

Reputation: 2054

What you are looking for is the @OnDelete annotation which affects schema generation by hibernate (DDL statements). This annotation does however not cascade deletes to referencing entities/rows in case of bulk delete when there is no ON DELETE CASCADE clause in the foreign key definition in the database.

@OneToMany
@OnDelete(action=OnDeleteAction.CASCADE)
public Set<Stuff> getStuff() {
  return stuff;
}

Upvotes: 7

Brad
Brad

Reputation: 15879

My understanding is that the 'ON DELETE CASCADE' feature you're referring to is a database trigger. Hibernate does not configure triggers. Using annotations, Hibernate will manage the deletion of child objects using standard SELECT and DELETE statements. If you turn debugging on you will see this happening. When you first start using hibernate this looks scarily inefficient, so that's when you look to use the bulk deletion via HQL you're referring to.

So table generation will not add database specific features like triggers. If you want to be able to remove child objects try something like this depending on your requirements

@OneToMany(cascade={CascadeType.ALL}, orphanRemoval=true)
private List<Case> cases = new ArrayList<Case>();

When using HQL directly it bypasses the cascading logic, so you may have to write your own "clean up" code that runs periodically to clean up orhapns etc. For efficiency I chose to write a stored procedure for this purpose.

The alternative is to retrieve the collection of parent objects you want to delete and loop through them one by one. If your collection is large this is not efficient but will at least cascade as you defined in your annontation.

Upvotes: 1

JB Nizet
JB Nizet

Reputation: 691635

This is expected behavior. The cascade annotation tells Hibernate to cascade the remove, and it's the responsibility of Hibernate, and not the database, to do so.

Bulk delete queries completely bypass the session and the entities cascade annotations. When you choose to use them, you have to handle the cascade deletes youself.

Upvotes: 2

Related Questions