Reputation: 14436
I found that JPA does not support the following Update:
Update Person p set p.name = :name_1 where p.id = :id_1,
p.name = :name_2 where p.id = :id_2,
p.name = :name_3 where p.id = :id_3
....
// It could go on, depending on the size of the input. Could be in 100s
So I have two options:
Option 1:
Query q = em.createQuery("Update Person p set p.name = :name where p.id = :id");
For ( int x=0; PersonsList.length; x++ ) {
// add name and id parameters
em.executeUpdate();
}
Questions:
hibernate.jdbc.batch_size", "20"
Option 2:
Construct one single query using either Select Case
syntax or with Criteria API
Questions:
Upvotes: 12
Views: 43743
Reputation: 153840
In your question title, you mentioned Bulk Update and Delete, but you actually need batching this time.
Bulk Update and Delete are needed when you want to UPDATE/DELETE rows that all match the same filtering criteria which can be expressed in the WHERE clause.
Here, you need JDBC batch updates. You need to set the following configuration property:
<property name="hibernate.jdbc.batch_size" value="50"/>
If you do this, you can simply update the entities, and Hibernate will batch the UPDATE statements for you.
Option 1 is not very useful because it will generate N UPDATE statements that cannot be batched.
Option 2 is not very useful either because it will generate a very complex query, whose Execution Plan is probably more complex than executing everything in a simple batched UPDATE statement.
So, do it like this:
If you have many such entities, use query pagination.
When using bulk updates, Hibernate does not increment the
version
column used for optimistic locking automatically, as it does for regular entity updates, so you need to increment theversion
entity attribute explicitly.
Upvotes: 6
Reputation: 1481
You can update a list of object without iterate over all the collection.
List<Integer> demo = Arrays.asList(1,2,3,4);
final String update = "UPDATE User u SET u.enabled = true WHERE u.id IN (?1)";
return super.getEntityManager()
.createQuery(update)
.setParameter(1, ids)
.executeUpdate();
Upvotes: 6
Reputation: 2323
If you are going to use batch see this chapter of the hibernate documentation
The batch_size is more to memory optimization than query optimization, the query is remain the same, but you can also minimize the roundtrip by the full use of your memory. you need to flush() and clear() each N times depend of the setting of batch_size.
but still . .
Update in 1 statement is much faster than update in multiple statement, so if you :
Then you can consider to just create native query than hql.
Upvotes: 2