Hibernate 中的级联删除:从表中删除的顺序是什么?

Cascading delete in Hibernate: What order to delete from tables?

在我的 Java 应用程序中,我试图 运行 一个有子对象的父对象 cascade delete

当我 运行 应用程序时,我收到以下错误:

java.sql.SQLIntegrityConstraintViolationException: ORA-02292: integrity constraint  violated - child record found

我搜索了这个错误,here 它指出这是由于:

You tried to DELETE a record from a parent table (as referenced by a foreign key), but a record in the child table exists.

是否需要先删除所有子表?我认为级联删除背后的想法是自动?

代码:

EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("myclasses");
                EntityManager em = entityManagerFactory.createEntityManager();
                Session session = em.unwrap(Session.class);

    Transaction transaction = session.beginTransaction();
            try {

               String hqlDelete = "DELETE FROM product WHERE price='PRICED'";
                Query queryDelete = session.createQuery(hqlDelete);
                queryDelete.executeUpdate();

               transaction.commit();
            } catch (Throwable t) {
                transaction.rollback();
                throw t;
            }

你做的就是所谓的bulk delete。它是高性能的,但有一些缺点:

  • 不尊重级联
  • 不能使用连接(有点合乎逻辑)

您之前可以删除子实体,这是最高效的解决方案。

还有另一种解决方案,利用 Cascade 选项(实际上它是反模式,如果应该删除很多行) - 您可以遍历要删除的实体并调用 Session.delete() 每个。

更新

假设您在 ParentChildren 实体之间有 @OneToMany 关联,您可以简单地询问所有 Children 会受到影响的并事先删除它们:

session
  .createQuery("DELETE FROM Children c WHERE EXISTS (SELECT p FROM Parent p WHERE p.price='PRICED' AND c IN p.children)")
  .executeUpdate();

然后您可以安全地删除您的 Parent 实体:

session
  .createQuery("DELETE FROM Parent p WHERE p.price='PRICED'")
  .executeUpdate();

更简洁但性能较差的方法是查询所有 Parent 个要删除的实体,然后手动删除它们:

List<Parent> parents = session
  .createQuery("SELECT p FROM Parent p WHERE p.price='PRICED'");
for (Parent parent : parents) {
    session.delete(parent);
}