繁体   English   中英

休眠级联删除对象

[英]Hibernate delete objects on cascade

我对级联=“删除”的工作方式感到困惑。 我在“城市”映射文件中以以下方式定义了映射:

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

类客户具有类城市的外键。

因此,当我运行时:

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()方法? 谢谢你的帮助。 最好的问候,混蛋。

我对cascade =“ delete”的工作方式有些困惑(...)

级联delete操作意味着,如果delete父级,则该操作将沿关联传播。 因此,在您的情况下,删除City实体应传播给Client

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

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

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

如果这是一个问题,请使用Hibernate提供的批量删除支持:

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

但是请注意,批量删除有一些限制:

  • 您不能使用别名。
  • 查询中没有内部联接(尽管您可以在where子句中使用子选择)。
  • 批量删除不会级联 (并且不会处理联接表)。

因此,如果要进行批量删除,则必须在City之前删除Client 但是性能要好得多。

PS:您需要在某个时候commit() (并且还要改善错误处理,即catch块中的rollback()

参考文献

  1. 如果删除城市,则所有客户端也将被删除。 如果删除客户端,则该城市将被保留。

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

另外,您可以使用session.createSQLQuery()创建删除语句。 这样一来,您就可以删除许多城市。 这种方法的缺点是必须自己删除客户端刷新缓存(Hibernate不会尝试理解查询的含义)。

暂无
暂无

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

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