Skip to content

Commit 9898221

Browse files
committed
Return deleted entity from derived deleteBy method.
We now return the deleted entity and check, guard the delete query against batch deletes if the delete yields more than done result. Closes #3995
1 parent 2c10b5e commit 9898221

File tree

3 files changed

+57
-2
lines changed

3 files changed

+57
-2
lines changed

spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryExecution.java

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import org.springframework.core.convert.ConversionService;
3030
import org.springframework.core.convert.support.ConfigurableConversionService;
3131
import org.springframework.core.convert.support.DefaultConversionService;
32+
import org.springframework.dao.IncorrectResultSizeDataAccessException;
3233
import org.springframework.dao.InvalidDataAccessApiUsageException;
3334
import org.springframework.data.domain.Pageable;
3435
import org.springframework.data.domain.ScrollPosition;
@@ -43,6 +44,7 @@
4344
import org.springframework.lang.Nullable;
4445
import org.springframework.util.Assert;
4546
import org.springframework.util.ClassUtils;
47+
import org.springframework.util.CollectionUtils;
4648
import org.springframework.util.ReflectionUtils;
4749

4850
/**
@@ -290,16 +292,33 @@ public DeleteExecution(EntityManager em) {
290292
}
291293

292294
@Override
293-
protected Object doExecute(AbstractJpaQuery jpaQuery, JpaParametersParameterAccessor accessor) {
295+
protected @Nullable Object doExecute(AbstractJpaQuery jpaQuery, JpaParametersParameterAccessor accessor) {
294296

295297
Query query = jpaQuery.createQuery(accessor);
296298
List<?> resultList = query.getResultList();
297299

300+
boolean simpleBatch = Number.class.isAssignableFrom(jpaQuery.getQueryMethod().getReturnType())
301+
|| org.springframework.data.util.ReflectionUtils.isVoid(jpaQuery.getQueryMethod().getReturnType());
302+
boolean collectionQuery = jpaQuery.getQueryMethod().isCollectionQuery();
303+
304+
if (!simpleBatch && !collectionQuery) {
305+
306+
if (resultList.size() > 1) {
307+
throw new IncorrectResultSizeDataAccessException(
308+
"Delete query returned more than one element: expected 1, actual " + resultList.size(), 1,
309+
resultList.size());
310+
}
311+
}
312+
298313
for (Object o : resultList) {
299314
em.remove(o);
300315
}
301316

302-
return jpaQuery.getQueryMethod().isCollectionQuery() ? resultList : resultList.size();
317+
if (simpleBatch) {
318+
return resultList.size();
319+
}
320+
321+
return collectionQuery ? resultList : CollectionUtils.firstElement(resultList);
303322
}
304323
}
305324

spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/UserRepositoryTests.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1557,6 +1557,38 @@ void deleteByShouldReturnListOfDeletedElementsWhenRetunTypeIsCollectionLike() {
15571557
assertThat(result).containsOnly(firstUser);
15581558
}
15591559

1560+
@Test // GH-3995
1561+
void deleteOneByShouldReturnDeletedElement() {
1562+
1563+
assertThat(repository.deleteOneByLastname(firstUser.getLastname())).isNull();
1564+
1565+
flushTestUsers();
1566+
1567+
User result = repository.deleteOneByLastname(firstUser.getLastname());
1568+
assertThat(result).isEqualTo(firstUser);
1569+
}
1570+
1571+
@Test // GH-3995
1572+
void deleteOneOptionalByShouldReturnDeletedElement() {
1573+
1574+
flushTestUsers();
1575+
1576+
Optional<User> result = repository.deleteOneOptionalByLastname(firstUser.getLastname());
1577+
assertThat(result).contains(firstUser);
1578+
}
1579+
1580+
@Test // GH-3995
1581+
void deleteOneShouldFailWhenMatchingMultipleResults() {
1582+
1583+
firstUser.setLastname("foo");
1584+
secondUser.setLastname("foo");
1585+
firstUser = repository.save(firstUser);
1586+
secondUser = repository.save(secondUser);
1587+
1588+
assertThatExceptionOfType(IncorrectResultSizeDataAccessException.class)
1589+
.isThrownBy(() -> repository.deleteOneByLastname(firstUser.getLastname()));
1590+
}
1591+
15601592
@Test // DATAJPA-460
15611593
void deleteByShouldRemoveElementsMatchingDerivedQuery() {
15621594

spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/sample/UserRepository.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,10 @@ Window<User> findTop3ByFirstnameStartingWithOrderByFirstnameAscEmailAddressAsc(S
299299
// DATAJPA-460
300300
List<User> deleteByLastname(String lastname);
301301

302+
User deleteOneByLastname(String lastname);
303+
304+
Optional<User> deleteOneOptionalByLastname(String lastname);
305+
302306
/**
303307
* @see <a href="https://issues.apache.org/jira/browse/OPENJPA-2484">OPENJPA-2484</a>
304308
*/

0 commit comments

Comments
 (0)