Search code examples
hibernatejpaeclipselinkcriteriajpa-2.1

Bulk delete in JPA 2.1 using the criteria API


Given the following code that deletes rows in a batch.

List<City> list = ...
int i=0;

for(City city:list)
{
    if(++i%49==0)
    {
        entityManager.flush();
    }

    entityManager.remove(city);
}

The JPA 2.1 criteria API provides CriteriaDelete to perform a bulk delete. Accordingly, the following code executes a DELETE FROM city WHERE id IN(...) query.

CriteriaBuilder criteriaBuilder=entityManager.getCriteriaBuilder();
CriteriaDelete<City> criteriaDelete = criteriaBuilder.createCriteriaDelete(City.class);

Root<City> root = criteriaDelete.from(City.class);
criteriaDelete.where(root.in(list));
entityManager.createQuery(criteriaDelete).executeUpdate();

But this should not be equivalent of the first case. What is the equivalent of the first case? It should perform deletion in a batch.


Solution

  • The equivalent would be to execute a query to delete a single entity in a for loop, something like:

    for(City city:list)
    {
        if(++i%49==0)
        {
            entityManager.flush();
        }
    
        CriteriaBuilder criteriaBuilder=entityManager.getCriteriaBuilder();
        CriteriaDelete<City> criteriaDelete = criteriaBuilder.createCriteriaDelete(City.class);
    
        Root<City> root = criteriaDelete.from(City.class);
        criteriaDelete.where(root.equal(city));
        entityManager.createQuery(criteriaDelete).executeUpdate();
    }
    

    Each of these 50 statements might not get put into the same batch - it depends on if your JPA provider supports batching or not. The loop seems less efficient, as you end up with X statements rather than a single DELETE FROM city WHERE id IN(...) you did with the original bulk delete.