diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/id/IdBinder.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/id/IdBinder.java
index 77982beccf..01aa079df6 100644
--- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/id/IdBinder.java
+++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/id/IdBinder.java
@@ -59,6 +59,13 @@ public interface IdBinder {
*/
boolean isComplexId();
+ /**
+ * Return the number of properties that make up the id.
+ */
+ default int size() {
+ return 1;
+ }
+
/**
* Return the default order by that may need to be used if the query includes
* a many property.
diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/id/IdBinderEmbedded.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/id/IdBinderEmbedded.java
index dec75f0015..ae3353aa91 100644
--- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/id/IdBinderEmbedded.java
+++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/id/IdBinderEmbedded.java
@@ -114,6 +114,11 @@ public boolean isComplexId() {
return true;
}
+ @Override
+ public int size() {
+ return props.length;
+ }
+
@Override
public String orderBy() {
return orderBy(null, true);
diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/DefaultPersister.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/DefaultPersister.java
index 8cb2eef030..a923adb2e8 100644
--- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/DefaultPersister.java
+++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/DefaultPersister.java
@@ -58,7 +58,7 @@ public DefaultPersister(SpiEbeanServer server, Binder binder, BeanDescriptorMana
* e.g. SqlServer has a 2100 parameter limit, so delete max 2000 for it.
*/
private int initMaxDeleteBatch(int maxInBinding) {
- return maxInBinding == 0 ? 1000 : maxInBinding;
+ return maxInBinding == 0 ? 1000 : Math.min(1000, maxInBinding);
}
@Override
@@ -652,11 +652,9 @@ public int deleteByIds(BeanDescriptor> descriptor, List
*/
void deleteManyDetails(SpiTransaction t, BeanDescriptor> desc, EntityBean parentBean,
BeanPropertyAssocMany> many, Set excludeDetailIds, DeleteMode deleteMode) {
if (many.cascadeInfo().isDelete()) {
// cascade delete the beans in the collection
- BeanDescriptor> targetDesc = many.targetDescriptor();
+ final BeanDescriptor> targetDesc = many.targetDescriptor();
+ final int batch = maxDeleteBatch / targetDesc.idBinder().size();
if (deleteMode.isHard() || targetDesc.isSoftDelete()) {
if (targetDesc.isDeleteByStatement()
- && (excludeDetailIds == null || excludeDetailIds.size() <= maxDeleteBatch)) { // TODO wait for #3176
+ && (excludeDetailIds == null || excludeDetailIds.size() <= batch)) {
// Just delete all the children with one statement
IntersectionRow intRow = many.buildManyDeleteChildren(parentBean, excludeDetailIds);
SqlUpdate sqlDelete = intRow.createDelete(server, deleteMode);
executeSqlUpdate(sqlDelete, t);
} else {
- // TODO: Review first checking if many property is loaded and using the loaded beans
- // ... and only using findIdsByParentId() when the many property isn't loaded
// Delete recurse using the Id values of the children
Object parentId = desc.getId(parentBean);
List idsByParentId;
- if (excludeDetailIds == null || excludeDetailIds.size() <= maxDeleteBatch) { // TODO: Wait for #3176
+ if (excludeDetailIds == null || excludeDetailIds.size() <= batch) {
idsByParentId = many.findIdsByParentId(parentId, t, deleteMode.isHard(), excludeDetailIds);
} else {
- // if we hit the parameter limit, we must filter that on the java side.
- // There is no easy way to batch "not in" queries.
- // checkme: We could pass the first 1000-2000 params to the DB and filter the rest
+ // if we hit the parameter limit, we must filter that on the java side
+ // as there is no easy way to batch "not in" queries.
idsByParentId = many.findIdsByParentId(parentId, t, deleteMode.isHard(), null);
- idsByParentId.removeIf(id -> excludeDetailIds.contains(id));
+ idsByParentId.removeIf(excludeDetailIds::contains);
}
if (!idsByParentId.isEmpty()) {
deleteChildrenById(t, targetDesc, idsByParentId, deleteMode);