Hibernate delete objects on cascade

sass picture sass · Sep 15, 2010 · Viewed 10.7k times · Source

I'm sligthly confused as to how the cascade="delete" works. I defined the mapping in the following way in the City mapping file:

<set inverse="true" name="client" cascade="delete">
  <key>
    <column name="id_name"/>
  </key>
    <one-to-many class="model.Client"/>
 </set>

The class Client has a foreign key to a class City.

So when I run:

List object = null;
try {
   org.hibernate.Transaction tx = session.beginTransaction();
   try {
       session.delete("from City where row_id=" + row_id and table_id = " + table_id);
   } catch (Exception e) {
       e.printStackTrace();
   }
}

Should all the clients be deleted as well or do I have to handle it somehow? Am I passing the query as a method parameter correctly to the delete() method of a session? Thanks for any help. Best Regards, sass.

Answer

Pascal Thivent picture Pascal Thivent · Sep 15, 2010

I'm slightly confused as to how the cascade="delete" works (...)

Cascading a delete operation means that if you delete a parent, the operation will be propagated along the association. So in your case, deleting a City entity should be propagated to the Clients.

So when I run (...) Should all the clients be deleted as well

The Session#delete(String) method that takes a HQL query string, executes it, iterates over the results and calls Session#delete(Object) on each object respect cascading (so the Clients will be deleted if your query is really a HQL query).

But this method is old and has been deprecated in Hibernate 3 (and moved to the "classic" Session interface), I do not really recommend it (it performs 1+N operations and is pretty inefficient to delete a huge number of results).

If this is a concern, prefer the bulk delete support offered by Hibernate:

int deleteCount = session.createQuery("delete from Foo where bar = :bar") 
    .setParameter("bar", bar);
    .executeUpdate()

But note that bulk delete has restrictions:

  • You can not use aliases.
  • No inner joins in the query (although you can use subselects in the where clause).
  • A bulk delete does not cascade (and won't take care of join tables).

So with a bulk delete, you'd have to delete the Client before the City. But performances are much better.

PS: You need to commit() at some point (and also improve your error handling i.e. rollback() in the catch block)

References