Skip to content

Commit 59f178b

Browse files
Batch deletes (orphanRemoval = true)
1 parent f0f375c commit 59f178b

File tree

1 file changed

+1
-1
lines changed
  • HibernateSpringBootBatchDeleteOrphanRemoval

1 file changed

+1
-1
lines changed

HibernateSpringBootBatchDeleteOrphanRemoval/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
**Description:** Batch deletes in MySQL via `orphanRemoval=true`.
66

7-
**Note:** Spring `deleteAllInBatch()` and `deleteInBatch()` don't use batching, don't take advantage of optimistic locking to prevent *lost updates* and don't take advantage of `orphanRemoval=true`. They trigger *bulk* operations and the Persistent Context is not synchronized accordingly (it is advisable to flush (before delete) and close/clear (after delete) the Persistent Context accordingly to avoid issues created by unflushed (if any) or outdated (if any) entities). The first one simply triggers a `delete from entity_name` statement, while the second one triggers a `delete from entity_name where id=? or id=? or id=? ...` statement. Using these methods for deleting parent-entities and the associated entites (child-entities) requires explicit calls for both sides. For batching rely on `deleteAll()`, `deleteAll(Iterable<? extends T> entities)` or even better, on `delete()` method. Behind the scene, `deleteAll()` methods uses `delete()`. The `delete()` and `deleteAll()` methods rely on `EntityManager.remove()`, therefore, the Persistent Context is synchronized. Moreover, cascading removals and `orphanRemoval` are taken into account.
7+
**Note:** Spring `deleteAllInBatch()` and `deleteInBatch()` don't use delete batching and don't take advantage of cascading removal, `orphanRemoval` and automatic optimstic locking mechanism to prevent *lost updates* (e.g., `@Version` is ignored). They rely on `Query.executeUpdate()` to trigger *bulk* operations. These operations are fast, but Hibernate doesn’t know which entities are removed, therefore, the Persistence Context is not updated accordingly (it's up to you to flush (before delete) and close/clear (after delete) the Persistence Context accordingly to avoid issues created by unflushed (if any) or outdated (if any) entities). The first one (`deleteAllInBatch()`) simply triggers a `delete from entity_name` statement and is very useful for deleting all records. The second one (`deleteInBatch()`) triggers a `delete from entity_name where id=? or id=? or id=? ...` statement, therefore, is prone to cause issues if the generated `DELETE` statement exceedes the maximum accepted size. This issue can be controlled by deleting the data in chunks, relying on `IN` operator, and so on. *Bulk* operations are faster than batching which can be achieved via the `deleteAll()`, `deleteAll(Iterable<? extends T> entities)` or `delete()` method. Behind the scene, the two flavors of `deleteAll()` relies on `delete()`. The `delete()`/`deleteAll()` methods rely on `EntityManager.remove()` therefore the Persistence Context is synchronized accordingly. If automatic optimstic locking mechanism (to prevent *lost updates*) is enabled then it will be used. Moreover, cascading removals and `orphanRemoval` works as well.
88

99
**Key points for using `deleteAll()/delete()`:**
1010
- in this example, we have a `Author` entity and each author can have several `Book` (*one-to-many*)

0 commit comments

Comments
 (0)