Criteria Update/Delete – The easy way to implement bulk operations with JPA2.1

By Thorben Janssen

Criteria API, Query

JPA 2.1 added a list of nice features to the specification. One of them is the support for bulk update and delete operations in the Criteria API. We will have a look at the new CriteriaUpdate and CriteriaDelete classes in this article.

If you like to learn more about the other features added in JPA 2.1, have a look at this overview or download the free New Features in JPA 2.1 cheat sheet.

CriteriaUpdate

The CriteriaUpdate interface can be used to implement bulk update operations. But be careful, these operations are directly mapped to database update operations. Therefore the persistence context is not synchronized with the result and there is no optimistic locking of the involved entities. If you use optimistic locking, you need to update the version column as part of your update statement.

The following code shows a bulk update of the amount of multiple orders.

As you can see, the implementation is very similar to implementing a CriteriaQuery known from JPA2.0. The main differences are the usage of the CriteriaUpdate interface and the call of the update specific set method.

CriteriaDelete

The usage of the CriteriaDelete interface for bulk delete operations is nearly the same as of the CriteriaUpdate interface. Like the CriteriaUpdate operations, the CriteriaDelete operations are directly mapped to database delete operations. Therefore the persistence context is not synchronized with the result of this operation.

The example of a CriteriaDelete operation looks similar to the usage of CriteriaQuery known from JPA2.0 and the CriteriaUpdate operation described above:

OK, I don’t think this needs any explanation …

Conclusion

The new CriteriaUpdate and CriteriaDelete interfaces add the missing bulk update and delete operations to the Criteria API. From my point of view this is a small but great enhancement that allows us to use the Criteria API in even more situations. I like it!
If you want to try it yourself, you can use any JPA 2.1 implementation like Hibernate or EclipseLink . You can find the source code of the examples in my github repo.

And don’t forget to download your New Features in JPA 2.1 cheat sheet.

And if you like to read more about the new JPA 2.1 features, make sure to have a look at my other articles …


Tags

Criteria API, Query


About the author

Thorben is an independent consultant, international speaker, and trainer specialized in solving Java persistence problems with JPA and Hibernate.
He is also the author of Amazon’s bestselling book Hibernate Tips - More than 70 solutions to common Hibernate problems.

Books and Courses

Coaching and Consulting

Leave a Repl​​​​​y

Your email address will not be published. Required fields are marked

This site uses Akismet to reduce spam. Learn how your comment data is processed.

  1. I have a question for you.

    what happen if I have million of records will affeted.

    can the CriteriaUpdate handle millions of the records

    Reply

    1. JPA/Hibernate just create an SQL UPDATE statement and send it to the database. So, from their point of view, it doesn’t matter how many records are affected.
      The only question is if your database can handle the update. That’s impossible to answer without knowing your DBMS, the table structure, the update statement and the number of affected records. In general, I wouldn’t expect any issues. Databases handle these kinds of operations very efficiently. If you’re worried about it, please ask your DBA to take a look at it.

      Reply

  2. Hi Thorben, since these operations are not synced with the persistence context does that mean that they will also not synchronise with Hibernate Search also? ie if I used criteriaDelete to bulk delete records from the db would I manually have to delete them from the lucene index too?

    Reply

    1. Hi Martin,

      so far, I didn’t use these updates/deletes together with Hibernate Search. But I would expect that you have to update the index manually.
      Hibernate doesn’t know which entities were changed/deleted and I don’t see how it should update the index.
      But as I said, I haven’t tried it.

      Regards,
      Thorben

      Reply

  3. First of all thank you for posting this website. It is amazing that I can have so many answers to my questions here.
    Can you please provide the same example, but using metamodel?
    Thanks.

    Reply

    1. First of all thank you for posting this website. It is amazing that I can have so many answers to my questions here.
      Can you please provide the same example, but using metamodel?
      Thanks.

      I tried to use this code, but update is not of type CriteriaQuery. It is of type Criteriaupdate. As a result when I try to write this.em.creteQuery (update) as you suggest the IDE forces me to cast it to CriteriaQuery.
      Have not check that it works yet but is this correct?

      Reply

      1. Hi,

        the JPA 2.1 EntityManager provides different variations of the createQuery method. One of them expects a CriteriaUpdate object: https://docs.jboss.org/hibernate/jpa/2.1/api/javax/persistence/EntityManager.html#createQuery(javax.persistence.criteria.CriteriaUpdate)
        and another one a CriteriaDelete object: https://docs.jboss.org/hibernate/jpa/2.1/api/javax/persistence/EntityManager.html#createQuery(javax.persistence.criteria.CriteriaDelete)

        So a cast to CriteriaQuery is not required.

        Regards,
        Thorben

        Reply

    2. Hi,

      using the JPA metamodel is quite simple. You just need to create the metamodel classes and replace “amount” with Order_.amount.
      I’ll publish a more detailed post about it next week.

      Regards,
      Thorben

      Reply

{"email":"Email address invalid","url":"Website address invalid","required":"Required field missing"}