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

时间:2011-12-19 05:49:34

标签: 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();
}

我在日志文件中看到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)

我有单线程。

更新

我也试过

for (Visitor obj : map.keySet())
    em.remove(obj);

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

2 个答案:

答案 0 :(得分:4)

经过多次实验,我最终做了hacky JPQL查询。这是code-snippet:

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

我尝试了5000个ID的列表。它适用于mysql 5.1和H2DB。

答案 1 :(得分:2)

尝试使用JPQL

em.createQuery("delete from  Visitor v where v.id in (:param)")
.setParameter("param", idsList).executeUpdate();

OpenJPA docs:http://openjpa.apache.org/builds/1.2.0/apache-openjpa-1.2.0/docs/manual/jpa_langref.html#jpa_langref_bulk_ops