DATAJPA-1818 - Implements CrudRepository.deleteAllById(Iterable<ID> ids).
Handling of IN-Queries in Eclipselink is still broken so this properly works only with Hibernate. Original pull request: #435.
This commit is contained in:
committed by
Mark Paluch
parent
e2db96193c
commit
38457e6d40
@@ -84,6 +84,19 @@ public interface JpaRepository<T, ID> extends PagingAndSortingRepository<T, ID>,
|
||||
*/
|
||||
void deleteInBatch(Iterable<T> entities);
|
||||
|
||||
|
||||
/**
|
||||
* Deletes the entities identified by the given ids using a single {@link Query}.
|
||||
*
|
||||
* This kind of operation leaves JPAs first level cache and the database out of sync.
|
||||
* Consider flushing the `EntityManager` before calling this method.
|
||||
*
|
||||
* @param ids
|
||||
*
|
||||
* @since 3.0
|
||||
*/
|
||||
void deleteAllByIdInBatch(Iterable<ID> ids);
|
||||
|
||||
/**
|
||||
* Deletes all entities in a batch call.
|
||||
*/
|
||||
|
||||
@@ -86,6 +86,7 @@ public abstract class QueryUtils {
|
||||
|
||||
public static final String COUNT_QUERY_STRING = "select count(%s) from %s x";
|
||||
public static final String DELETE_ALL_QUERY_STRING = "delete from %s x";
|
||||
public static final String DELETE_ALL_QUERY_BY_ID_STRING = "delete from %s x where %s in :ids";
|
||||
|
||||
// Used Regex/Unicode categories (see https://www.unicode.org/reports/tr18/#General_Category_Property):
|
||||
// Z Separator
|
||||
|
||||
@@ -218,6 +218,16 @@ public class SimpleJpaRepository<T, ID> implements JpaRepositoryImplementation<T
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteAllById(Iterable<? extends ID> ids) {
|
||||
|
||||
Assert.notNull(ids, "Ids must not be null!");
|
||||
|
||||
for (ID id : ids) {
|
||||
deleteById(id);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.jpa.repository.JpaRepository#deleteInBatch(java.lang.Iterable)
|
||||
@@ -236,6 +246,24 @@ public class SimpleJpaRepository<T, ID> implements JpaRepositoryImplementation<T
|
||||
.executeUpdate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteAllByIdInBatch(Iterable<ID> ids) {
|
||||
|
||||
Assert.notNull(ids, "Ids must not be null!");
|
||||
|
||||
if (!ids.iterator().hasNext()) {
|
||||
return;
|
||||
}
|
||||
|
||||
String queryTemplate = DELETE_ALL_QUERY_BY_ID_STRING;
|
||||
String queryString = String.format(queryTemplate, entityInformation.getEntityName(), entityInformation.getIdAttribute().getName());
|
||||
|
||||
Query query = em.createQuery(queryString);
|
||||
query.setParameter("ids", ids);
|
||||
|
||||
query.executeUpdate();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.Repository#deleteAll()
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package org.springframework.data.jpa.repository;
|
||||
|
||||
import static java.util.Arrays.*;
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
import static org.springframework.data.domain.Example.*;
|
||||
import static org.springframework.data.domain.ExampleMatcher.*;
|
||||
@@ -151,7 +152,7 @@ public class UserRepositoryTests {
|
||||
|
||||
flushTestUsers();
|
||||
|
||||
assertThat(repository.findAllById(Arrays.asList(firstUser.getId(), secondUser.getId()))).contains(firstUser,
|
||||
assertThat(repository.findAllById(asList(firstUser.getId(), secondUser.getId()))).contains(firstUser,
|
||||
secondUser);
|
||||
}
|
||||
|
||||
@@ -166,7 +167,7 @@ public class UserRepositoryTests {
|
||||
@Test
|
||||
void savesCollectionCorrectly() throws Exception {
|
||||
|
||||
assertThat(repository.saveAll(Arrays.asList(firstUser, secondUser, thirdUser))).hasSize(3).contains(firstUser,
|
||||
assertThat(repository.saveAll(asList(firstUser, secondUser, thirdUser))).hasSize(3).contains(firstUser,
|
||||
secondUser, thirdUser);
|
||||
}
|
||||
|
||||
@@ -238,13 +239,13 @@ public class UserRepositoryTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void deleteColletionOfEntities() {
|
||||
void deleteCollectionOfEntities() {
|
||||
|
||||
flushTestUsers();
|
||||
|
||||
long before = repository.count();
|
||||
|
||||
repository.deleteAll(Arrays.asList(firstUser, secondUser));
|
||||
repository.deleteAll(asList(firstUser, secondUser));
|
||||
|
||||
assertThat(repository.existsById(firstUser.getId())).isFalse();
|
||||
assertThat(repository.existsById(secondUser.getId())).isFalse();
|
||||
@@ -252,13 +253,27 @@ public class UserRepositoryTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void batchDeleteColletionOfEntities() {
|
||||
void batchDeleteCollectionOfEntities() {
|
||||
|
||||
flushTestUsers();
|
||||
|
||||
long before = repository.count();
|
||||
|
||||
repository.deleteInBatch(Arrays.asList(firstUser, secondUser));
|
||||
repository.deleteInBatch(asList(firstUser, secondUser));
|
||||
|
||||
assertThat(repository.existsById(firstUser.getId())).isFalse();
|
||||
assertThat(repository.existsById(secondUser.getId())).isFalse();
|
||||
assertThat(repository.count()).isEqualTo(before - 2);
|
||||
}
|
||||
|
||||
@Test // DATAJPA-1818
|
||||
void deleteCollectionOfEntitiesById() {
|
||||
|
||||
flushTestUsers();
|
||||
|
||||
long before = repository.count();
|
||||
|
||||
repository.deleteAllById(asList(firstUser.getId(), secondUser.getId()));
|
||||
|
||||
assertThat(repository.existsById(firstUser.getId())).isFalse();
|
||||
assertThat(repository.existsById(secondUser.getId())).isFalse();
|
||||
@@ -603,7 +618,7 @@ public class UserRepositoryTests {
|
||||
|
||||
firstUser.setManager(secondUser);
|
||||
thirdUser.setManager(firstUser);
|
||||
repository.saveAll(Arrays.asList(firstUser, thirdUser));
|
||||
repository.saveAll(asList(firstUser, thirdUser));
|
||||
|
||||
assertThat(repository.findByManagerLastname("Arrasz")).containsOnly(firstUser);
|
||||
assertThat(repository.findByManagerLastname("Gierke")).containsOnly(thirdUser);
|
||||
@@ -616,7 +631,7 @@ public class UserRepositoryTests {
|
||||
|
||||
firstUser.addColleague(secondUser);
|
||||
thirdUser.addColleague(firstUser);
|
||||
repository.saveAll(Arrays.asList(firstUser, thirdUser));
|
||||
repository.saveAll(asList(firstUser, thirdUser));
|
||||
|
||||
assertThat(repository.findByColleaguesLastname(secondUser.getLastname())).containsOnly(firstUser);
|
||||
|
||||
@@ -1178,7 +1193,7 @@ public class UserRepositoryTests {
|
||||
|
||||
flushTestUsers();
|
||||
|
||||
List<User> result = repository.findByAttributesIn(new HashSet<>(Arrays.asList("cool", "hip")));
|
||||
List<User> result = repository.findByAttributesIn(new HashSet<>(asList("cool", "hip")));
|
||||
|
||||
assertThat(result).containsOnly(firstUser, secondUser);
|
||||
}
|
||||
@@ -1731,7 +1746,7 @@ public class UserRepositoryTests {
|
||||
|
||||
firstUser.setManager(secondUser);
|
||||
thirdUser.setManager(firstUser);
|
||||
repository.saveAll(Arrays.asList(firstUser, thirdUser));
|
||||
repository.saveAll(asList(firstUser, thirdUser));
|
||||
|
||||
User manager = new User();
|
||||
manager.setLastname("Arrasz");
|
||||
@@ -1854,7 +1869,7 @@ public class UserRepositoryTests {
|
||||
fifthUser.setFirstname(firstUser.getFirstname());
|
||||
fifthUser.setLastname(firstUser.getLastname());
|
||||
|
||||
repository.saveAll(Arrays.asList(firstUser, fifthUser));
|
||||
repository.saveAll(asList(firstUser, fifthUser));
|
||||
|
||||
User prototype = new User();
|
||||
prototype.setFirstname(firstUser.getFirstname());
|
||||
@@ -2242,7 +2257,7 @@ public class UserRepositoryTests {
|
||||
|
||||
flushTestUsers();
|
||||
|
||||
List<User> result = repository.findByAttributesIgnoreCaseIn(new HashSet<>(Arrays.asList("cOOl", "hIP")));
|
||||
List<User> result = repository.findByAttributesIgnoreCaseIn(new HashSet<>(asList("cOOl", "hIP")));
|
||||
|
||||
assertThat(result).containsOnly(firstUser, secondUser);
|
||||
}
|
||||
@@ -2256,7 +2271,7 @@ public class UserRepositoryTests {
|
||||
|
||||
flushTestUsers();
|
||||
|
||||
List<User> result = repository.findByAttributesIgnoreCaseNotIn(Arrays.asList("CooL", "HIp"));
|
||||
List<User> result = repository.findByAttributesIgnoreCaseNotIn(asList("CooL", "HIp"));
|
||||
|
||||
assertThat(result).containsOnly(thirdUser);
|
||||
}
|
||||
@@ -2284,7 +2299,7 @@ public class UserRepositoryTests {
|
||||
|
||||
flushTestUsers();
|
||||
|
||||
List<User> result = repository.findByAttributesIgnoreCaseIn(Arrays.asList("cOOl", null));
|
||||
List<User> result = repository.findByAttributesIgnoreCaseIn(asList("cOOl", null));
|
||||
|
||||
assertThat(result).containsOnly(firstUser);
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package org.springframework.data.jpa.repository.support;
|
||||
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
|
||||
/**
|
||||
@@ -25,4 +26,11 @@ import org.springframework.test.context.ContextConfiguration;
|
||||
@ContextConfiguration("classpath:eclipselink.xml")
|
||||
class EclipseLinkJpaRepositoryTests extends JpaRepositoryTests {
|
||||
|
||||
@Override
|
||||
/**
|
||||
* Ignored until https://bugs.eclipse.org/bugs/show_bug.cgi?id=349477 is resolved.
|
||||
*/
|
||||
void deleteAllByIdInBatch() {
|
||||
super.deleteAllByIdInBatch();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,11 +114,24 @@ class JpaRepositoryTests {
|
||||
assertThat(idClassRepository.existsById(id)).isTrue();
|
||||
}
|
||||
|
||||
private static interface SampleEntityRepository extends JpaRepository<SampleEntity, SampleEntityPK> {
|
||||
@Test // DATAJPA-1818
|
||||
void deleteAllByIdInBatch() {
|
||||
|
||||
SampleEntity one = new SampleEntity("one", "eins");
|
||||
SampleEntity two = new SampleEntity("two", "zwei");
|
||||
SampleEntity three = new SampleEntity("three", "drei");
|
||||
repository.saveAll(Arrays.asList(one, two, three));
|
||||
repository.flush();
|
||||
|
||||
repository.deleteAllByIdInBatch(Arrays.asList(new SampleEntityPK("one", "eins"),new SampleEntityPK("three", "drei")));
|
||||
assertThat(repository.findAll()).containsExactly(two);
|
||||
}
|
||||
|
||||
private interface SampleEntityRepository extends JpaRepository<SampleEntity, SampleEntityPK> {
|
||||
|
||||
}
|
||||
|
||||
private static interface SampleWithIdClassRepository
|
||||
private interface SampleWithIdClassRepository
|
||||
extends CrudRepository<PersistableWithIdClass, PersistableWithIdClassPK> {
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user