我对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()方法?谢谢你的帮助。 最好的祝福, SASS。
答案 0 :(得分:7)
我对cascade =“delete”如何工作(...)
感到有些困惑
级联delete
操作意味着如果您delete
为父级,则操作将沿着关联传播。因此,在您的情况下,删除City
实体应该传播到Client
。
所以当我跑(...)时,所有客户都应该被删除
采用 HQL查询字符串的Session#delete(String)
方法,执行它,迭代结果并在每个对象上调用Session#delete(Object)
级联(因此客户端将被删除)如果你的查询真的是一个HQL查询。)
但是这个方法很老,在Hibernate 3中已被弃用(并转移到“经典”Session
接口),我不推荐它(它执行1 + N操作并且删除效率很低)大量的结果)。
如果这是一个问题,请选择Hibernate提供的批量删除支持:
int deleteCount = session.createQuery("delete from Foo where bar = :bar")
.setParameter("bar", bar);
.executeUpdate()
但请注意,批量删除有限制:
因此,对于批量删除,您必须在Client
之前删除City
。但表现要好得多。
PS:您需要commit()
某些时候(并且还会改进您的错误处理,即catch块中的rollback()
)
答案 1 :(得分:0)
如果删除城市,则也会删除所有客户端。如果您删除了一个客户端,该城市将被单独留下。
session.delete()
。您必须将其传递给一个城市才能删除。
或者,您可以使用session.createSQLQuery()
创建删除语句。这允许您一次删除许多城市。这种方法的缺点是你必须自己删除客户端和刷新缓存(Hibernate不会试图理解你的查询可能意味着什么)。