在我的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;
}
答案 0 :(得分:3)
你所做的就是所谓的bulk delete
。它具有高性能,但有一些缺点:
您之前可以删除子实体,什么是最高性能的解决方案。
还有另一种解决方案,即使用Cascade
选项(如果应该删除许多行,实际上它是反模式) - 您可以迭代要删除的实体并调用Session.delete()
每个
更新
假设@OneToMany
和Parent
实体之间存在Children
关联,您可以直接询问受影响的所有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);
}