在我的 Java
应用程序中,我尝试在具有子项的父对象上运行级联删除
。
当我运行应用程序时,出现以下错误:
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;
}
最佳答案
您所做的就是所谓的批量删除
。它的性能很好,但也有一些缺点:
- 不尊重级联
- 不能使用连接(这有点合乎逻辑)
您可以之前删除子实体,这将是最高效的解决方案。
还有另一种解决方案,即使用 Cascade
选项(实际上,如果应删除许多行,则这是反模式) - 您可以迭代要删除的实体并调用 每个Session.delete()
。
更新
假设您在 Parent
和 Children
实体之间具有 @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);
}
关于java - Hibernate中级联删除: What order to delete from tables?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35507382/