如何使用它们的 ID 在批量调用中删除多个对象?

exp*_*ert 3 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.getTransaction().commit();
}
catch (Exception ex)
{
    ex.printStackTrace();
}
Run Code Online (Sandbox Code Playgroud)

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)
Run Code Online (Sandbox Code Playgroud)

我有单线程。

更新:

我也试过

for (Visitor obj : map.keySet())
    em.remove(obj);
Run Code Online (Sandbox Code Playgroud)

但它很慢,因为在每次迭代时它都会发送SELECT到服务器。我假设 OpenJPA 这样做是为了将对象重新附加到上下文。

exp*_*ert 5

经过多次实验,我最终完成了 hacky JPQL 查询。这是代码片段:

List<Long> lstExistingVisitors = ...
Query qDeleteVisitors = em.createQuery("delete from Visitor obj where obj.id in (?1)");
qDeleteVisitors.setParameter(1, lstExistingVisitors);
qDeleteVisitors.executeUpdate();
Run Code Online (Sandbox Code Playgroud)

我尝试列出多达 5000 个 ID。它适用于 mysql 5.1 和 H2DB。