Jpa 如何使用批处理调用中的多个对象的ID删除它们?
如何使用批处理调用中的多个对象的ID删除它们 我试过这个Jpa 如何使用批处理调用中的多个对象的ID删除它们?,jpa,jpa-2.0,Jpa,Jpa 2.0,如何使用批处理调用中的多个对象的ID删除它们 我试过这个 EntityManager em = ... em.getTransaction().begin(); try { for (Visitor obj : map.keySet()) { Visitor fake = em.getReference(Visitor.class, obj.getId()); em.remove(fake); } em.getTransactio
EntityManager em = ...
em.getTransaction().begin();
try
{
for (Visitor obj : map.keySet())
{
Visitor fake = em.getReference(Visitor.class, obj.getId());
em.remove(fake);
}
em.getTransaction().commit();
}
catch (Exception ex)
{
ex.printStackTrace();
}
我在日志文件中看到DELETE
语句,但它会抛出它们
<openjpa-2.1.1-r422266:1148538 fatal store error> org.apache.openjpa.persistence.RollbackException: Optimistic locking errors were detected when flushing to the data store. The following objects may have been concurrently modified in another transaction: [com.reporting.data.Visitor-53043]
at org.apache.openjpa.persistence.EntityManagerImpl.commit(EntityManagerImpl.java:593)
at com.reporting.ui.DBUtil.saveAnswers(DBUtil.java:311)
但它的速度很慢,因为在每次迭代中它都会将SELECT
发送到服务器。我假设OpenJPA这样做是为了将对象重新连接到上下文。尝试使用JPQL
em.createQuery("delete from Visitor v where v.id in (:param)")
.setParameter("param", idsList).executeUpdate();
OpenJPA文档:经过多次实验后,我最终完成了一个粗糙的JPQL查询。下面是代码片段:
List<Long> lstExistingVisitors = ...
Query qDeleteVisitors = em.createQuery("delete from Visitor obj where obj.id in (?1)");
qDeleteVisitors.setParameter(1, lstExistingVisitors);
qDeleteVisitors.executeUpdate();
List lstExistingVisitors=。。。
Query qDeleteVisitors=em.createQuery(“从访问对象中删除,其中obj.id位于(?1)”);
setParameter(1,lsExistingVisitors);
qDeleteVisitors.executeUpdate();
我试着列出多达5000个ID的列表。它在mysql 5.1和H2DB上运行良好。不幸的是,Query.executeUpdate()会立即将查询发送到数据库。在我使用mysql+openjpa.em.commit进行测试之前,它不会对它们进行排队?您的事务管理刚刚完成。你的平台是什么?你没有交易经理吗?另一方面,即使它向DB发送语句,事务仍然可能未提交,并且您可以回滚更改。我不能在这里解决问题。问题是当我删除1K行时速度太慢。我不希望OpenJPA对DB进行任何往返调用。奇怪的是,
HibernateTemplate
有deleteAll()
,但EntityManager没有等效的方法。使用query-to-delete比remove方法快得多,但这种方法需要手动删除可能的子项。换句话说:如果性能需要,请使用query,否则通过循环和调用remove删除。
List<Long> lstExistingVisitors = ...
Query qDeleteVisitors = em.createQuery("delete from Visitor obj where obj.id in (?1)");
qDeleteVisitors.setParameter(1, lstExistingVisitors);
qDeleteVisitors.executeUpdate();