简体   繁体   English

休眠级联删除对象

[英]Hibernate delete objects on cascade

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? 我是否将查询作为方法参数正确传递给会话的delete()方法? Thanks for any help. 谢谢你的帮助。 Best Regards, sass. 最好的问候,混蛋。

I'm slightly confused as to how the cascade="delete" works (...) 我对cascade =“ delete”的工作方式有些困惑(...)

Cascading a delete operation means that if you delete a parent, the operation will be propagated along the association. 级联delete操作意味着,如果delete父级,则该操作将沿关联传播。 So in your case, deleting a City entity should be propagated to the Client s. 因此,在您的情况下,删除City实体应传播给Client

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). Session#delete(String)方法采用HQL查询字符串 ,执行该字符串 ,遍历结果,并在级联的每个对象上调用Session#delete(Object) (因此,如果您的查询确实是HQL查询,则将删除客户端)。

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). 但是此方法很旧,并且在Hibernate 3中已弃用(并移至“经典” Session接口),我并不推荐这样做(它执行1 + N操作,删除大量结果效率很低)。

If this is a concern, prefer the bulk delete support offered by Hibernate: 如果这是一个问题,请使用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). 查询中没有内部联接(尽管您可以在where子句中使用子选择)。
  • 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 . 因此,如果要进行批量删除,则必须在City之前删除Client But performances are much better. 但是性能要好得多。

PS: You need to commit() at some point (and also improve your error handling ie rollback() in the catch block) PS:您需要在某个时候commit() (并且还要改善错误处理,即catch块中的rollback()

References 参考文献

  1. If you delete a city, then all clients will be deleted as well. 如果删除城市,则所有客户端也将被删除。 If you delete a client, the city will be left alone. 如果删除客户端,则该城市将被保留。

  2. session.delete() can't be called with a HQL query. session.delete()不能与HQL查询一起调用。 You must pass it one city to delete. 您必须将其传递给一个城市才能删除。

Alternatively, you can use session.createSQLQuery() to create a delete statement. 另外,您可以使用session.createSQLQuery()创建删除语句。 That allows you to delete many cities in one go. 这样一来,您就可以删除许多城市。 The drawback with this method is that you must delete the clients yourself and flush the cache (Hibernate makes no attempt to understand what your query might mean). 这种方法的缺点是必须自己删除客户端刷新缓存(Hibernate不会尝试理解查询的含义)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM