Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Jpa 如何使用批处理调用中的多个对象的ID删除它们?_Jpa_Jpa 2.0 - Fatal编程技术网

Jpa 如何使用批处理调用中的多个对象的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

如何使用批处理调用中的多个对象的ID删除它们

我试过这个

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();