Update SaveBatchingAggregateChange to batch Delete actions.
Original pull request #1229
This commit is contained in:
committed by
Jens Schauder
parent
64d9bbbd55
commit
aa1610d381
@@ -92,6 +92,8 @@ class AggregateChangeExecutor {
|
||||
executionContext.executeUpdateRoot((DbAction.UpdateRoot<?>) action);
|
||||
} else if (action instanceof DbAction.Delete) {
|
||||
executionContext.executeDelete((DbAction.Delete<?>) action);
|
||||
} else if (action instanceof DbAction.BatchDelete<?>) {
|
||||
executionContext.executeBatchDelete((DbAction.BatchDelete<?>) action);
|
||||
} else if (action instanceof DbAction.DeleteAll) {
|
||||
executionContext.executeDeleteAll((DbAction.DeleteAll<?>) action);
|
||||
} else if (action instanceof DbAction.DeleteRoot) {
|
||||
|
||||
@@ -135,6 +135,12 @@ class JdbcAggregateChangeExecutionContext {
|
||||
accessStrategy.delete(delete.getRootId(), delete.getPropertyPath());
|
||||
}
|
||||
|
||||
<T> void executeBatchDelete(DbAction.BatchDelete<T> batchDelete) {
|
||||
|
||||
List<Object> rootIds = batchDelete.getActions().stream().map(DbAction.Delete::getRootId).toList();
|
||||
accessStrategy.delete(rootIds, batchDelete.getBatchValue());
|
||||
}
|
||||
|
||||
<T> void executeDeleteAllRoot(DbAction.DeleteAllRoot<T> deleteAllRoot) {
|
||||
|
||||
accessStrategy.deleteAll(deleteAllRoot.getEntityType());
|
||||
|
||||
@@ -87,6 +87,11 @@ public class CascadingDataAccessStrategy implements DataAccessStrategy {
|
||||
collectVoid(das -> das.delete(rootId, propertyPath));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(Iterable<Object> rootIds, PersistentPropertyPath<RelationalPersistentProperty> propertyPath) {
|
||||
collectVoid(das -> das.delete(rootIds, propertyPath));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> void deleteAll(Class<T> domainType) {
|
||||
collectVoid(das -> das.deleteAll(domainType));
|
||||
|
||||
@@ -152,6 +152,14 @@ public interface DataAccessStrategy extends RelationResolver {
|
||||
*/
|
||||
void delete(Object rootId, PersistentPropertyPath<RelationalPersistentProperty> propertyPath);
|
||||
|
||||
/**
|
||||
* Deletes all entities reachable via {@literal propertyPath} from the instances identified by {@literal rootIds}.
|
||||
*
|
||||
* @param rootIds Ids of the root objects on which the {@literal propertyPath} is based. Must not be {@code null} or empty.
|
||||
* @param propertyPath Leading from the root object to the entities to be deleted. Must not be {@code null}.
|
||||
*/
|
||||
void delete(Iterable<Object> rootIds, PersistentPropertyPath<RelationalPersistentProperty> propertyPath);
|
||||
|
||||
/**
|
||||
* Deletes all entities of the given domain type.
|
||||
*
|
||||
|
||||
@@ -196,6 +196,21 @@ public class DefaultDataAccessStrategy implements DataAccessStrategy {
|
||||
operations.update(delete, parameters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(Iterable<Object> rootIds, PersistentPropertyPath<RelationalPersistentProperty> propertyPath) {
|
||||
|
||||
RelationalPersistentEntity<?> rootEntity = context
|
||||
.getRequiredPersistentEntity(propertyPath.getBaseProperty().getOwner().getType());
|
||||
|
||||
RelationalPersistentProperty referencingProperty = propertyPath.getLeafProperty();
|
||||
Assert.notNull(referencingProperty, "No property found matching the PropertyPath " + propertyPath);
|
||||
|
||||
String delete = sql(rootEntity.getType()).createDeleteInByPath(propertyPath);
|
||||
|
||||
SqlIdentifierParameterSource parameters = sqlParametersFactory.forQueryByIds(rootIds, rootEntity.getType());
|
||||
operations.update(delete, parameters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> void deleteAll(Class<T> domainType) {
|
||||
operations.getJdbcOperations().update(sql(domainType).createDeleteAllSql(null));
|
||||
|
||||
@@ -71,6 +71,11 @@ public class DelegatingDataAccessStrategy implements DataAccessStrategy {
|
||||
delegate.delete(rootId, propertyPath);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(Iterable<Object> rootIds, PersistentPropertyPath<RelationalPersistentProperty> propertyPath) {
|
||||
delegate.delete(rootIds, propertyPath);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(Object id, Class<?> domainType) {
|
||||
delegate.delete(id, domainType);
|
||||
|
||||
@@ -360,7 +360,8 @@ class SqlGenerator {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a {@code DELETE} query and filter by {@link PersistentPropertyPath}.
|
||||
* Create a {@code DELETE} query and filter by {@link PersistentPropertyPath} using {@code WHERE} with the {@code =}
|
||||
* operator.
|
||||
*
|
||||
* @param path must not be {@literal null}.
|
||||
* @return the statement as a {@link String}. Guaranteed to be not {@literal null}.
|
||||
@@ -370,6 +371,18 @@ class SqlGenerator {
|
||||
filterColumn -> filterColumn.isEqualTo(getBindMarker(ROOT_ID_PARAMETER)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a {@code DELETE} query and filter by {@link PersistentPropertyPath} using {@code WHERE} with the {@code IN}
|
||||
* operator.
|
||||
*
|
||||
* @param path must not be {@literal null}.
|
||||
* @return the statement as a {@link String}. Guaranteed to be not {@literal null}.
|
||||
*/
|
||||
String createDeleteInByPath(PersistentPropertyPath<RelationalPersistentProperty> path) {
|
||||
return createDeleteByPathAndCriteria(new PersistentPropertyPathExtension(mappingContext, path),
|
||||
filterColumn -> filterColumn.in(getBindMarker(IDS_SQL_PARAMETER)));
|
||||
}
|
||||
|
||||
private String createFindOneSql() {
|
||||
|
||||
Select select = selectBuilder().where(getIdColumn().isEqualTo(getBindMarker(ID_SQL_PARAMETER))) //
|
||||
|
||||
@@ -218,6 +218,11 @@ public class MyBatisDataAccessStrategy implements DataAccessStrategy {
|
||||
sqlSession().delete(statement, parameter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(Iterable<Object> rootIds, PersistentPropertyPath<RelationalPersistentProperty> propertyPath) {
|
||||
rootIds.forEach(rootId -> delete(rootId, propertyPath));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> void deleteAll(Class<T> domainType) {
|
||||
|
||||
|
||||
@@ -147,6 +147,14 @@ class SqlGeneratorUnitTests {
|
||||
assertThat(sql).isEqualTo("DELETE FROM referenced_entity WHERE referenced_entity.dummy_entity = :rootId");
|
||||
}
|
||||
|
||||
@Test // GH-537
|
||||
void cascadingDeleteInByPathFirstLevel() {
|
||||
|
||||
String sql = sqlGenerator.createDeleteInByPath(getPath("ref", DummyEntity.class));
|
||||
|
||||
assertThat(sql).isEqualTo("DELETE FROM referenced_entity WHERE referenced_entity.dummy_entity IN (:ids)");
|
||||
}
|
||||
|
||||
@Test // DATAJDBC-112
|
||||
void cascadingDeleteByPathSecondLevel() {
|
||||
|
||||
@@ -156,6 +164,15 @@ class SqlGeneratorUnitTests {
|
||||
"DELETE FROM second_level_referenced_entity WHERE second_level_referenced_entity.referenced_entity IN (SELECT referenced_entity.x_l1id FROM referenced_entity WHERE referenced_entity.dummy_entity = :rootId)");
|
||||
}
|
||||
|
||||
@Test // GH-537
|
||||
void cascadingDeleteInByPathSecondLevel() {
|
||||
|
||||
String sql = sqlGenerator.createDeleteInByPath(getPath("ref.further", DummyEntity.class));
|
||||
|
||||
assertThat(sql).isEqualTo(
|
||||
"DELETE FROM second_level_referenced_entity WHERE second_level_referenced_entity.referenced_entity IN (SELECT referenced_entity.x_l1id FROM referenced_entity WHERE referenced_entity.dummy_entity IN (:ids))");
|
||||
}
|
||||
|
||||
@Test // DATAJDBC-112
|
||||
void deleteAll() {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user