4

我对 cascade="delete" 的工作原理感到有些困惑。我在 City 映射文件中通过以下方式定义了映射:

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

Client 类具有 City 类的外键。

所以当我运行时:

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();
   }
}

是否也应该删除所有客户端,还是我必须以某种方式处理它?我是否将查询作为方法参数正确传递给会话的 delete() 方法?谢谢你的帮助。最好的问候,萨斯。

4

2 回答 2

7

我对 cascade="delete" 的工作原理有点困惑(...)

级联delete操作意味着如果您delete是父级,则操作将沿关联传播。所以在你的情况下,删除一个City实体应该传播到Clients.

因此,当我运行 (...) 时,是否也应该删除所有客户端

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

于 2010-09-15T08:47:39.510 回答
0
  1. 如果您删除一个城市,那么所有客户端也将被删除。如果您删除客户,则该城市将被单独保留。

  2. session.delete()不能用 HQL 查询调用。您必须将其传递一个城市才能删除。

或者,您可以使用session.createSQLQuery()创建删除语句。这使您可以一次删除许多城市。这种方法的缺点是您必须自己删除客户端刷新缓存(Hibernate 不会尝试理解您的查询可能意味着什么)。

于 2010-09-15T07:41:28.427 回答