Convert Iterable<ID> to Collection<ID> for deleteAllByIdInBatch.
JpaRepository accepts Iterable<ID> for bulk deletes. But some JPA providers require Collection<ID> instead. To avoid breaking any APIs, convert the incoming argument if it's not already a Collection. See #2242.
This commit is contained in:
@@ -38,6 +38,8 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
import org.springframework.dao.EmptyResultDataAccessException;
|
||||
import org.springframework.data.domain.Example;
|
||||
@@ -223,7 +225,16 @@ public class SimpleJpaRepository<T, ID> implements JpaRepositoryImplementation<T
|
||||
entityInformation.getIdAttribute().getName());
|
||||
|
||||
Query query = em.createQuery(queryString);
|
||||
query.setParameter("ids", ids);
|
||||
/**
|
||||
* Some JPA providers require {@code ids} to be a {@link Collection} so we must convert if it's not already.
|
||||
*/
|
||||
if (Collection.class.isInstance(ids)) {
|
||||
query.setParameter("ids", ids);
|
||||
} else {
|
||||
Collection<ID> idsCollection = StreamSupport.stream(ids.spliterator(), false)
|
||||
.collect(Collectors.toCollection(ArrayList::new));
|
||||
query.setParameter("ids", idsCollection);
|
||||
}
|
||||
|
||||
query.executeUpdate();
|
||||
}
|
||||
|
||||
@@ -22,15 +22,20 @@ import org.springframework.test.context.ContextConfiguration;
|
||||
* Integration tests to execute {@link JpaRepositoryTests} against EclipseLink.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Greg Turnquist
|
||||
*/
|
||||
@ContextConfiguration("classpath:eclipselink.xml")
|
||||
class EclipseLinkJpaRepositoryTests extends JpaRepositoryTests {
|
||||
|
||||
@Override
|
||||
/**
|
||||
* Ignored until https://bugs.eclipse.org/bugs/show_bug.cgi?id=349477 is resolved.
|
||||
*/
|
||||
@Disabled("https://bugs.eclipse.org/bugs/show_bug.cgi?id=349477")
|
||||
void deleteAllByIdInBatch() {
|
||||
super.deleteAllByIdInBatch();
|
||||
// disabled
|
||||
}
|
||||
|
||||
@Override
|
||||
@Disabled("https://bugs.eclipse.org/bugs/show_bug.cgi?id=349477")
|
||||
void deleteAllByIdInBatchShouldConvertAnIterableToACollection() {
|
||||
// disabled
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,16 +17,18 @@ package org.springframework.data.jpa.repository.support;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Optional;
|
||||
|
||||
import jakarta.persistence.EntityManager;
|
||||
import jakarta.persistence.PersistenceContext;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
|
||||
import org.springframework.data.jpa.domain.sample.PersistableWithIdClass;
|
||||
import org.springframework.data.jpa.domain.sample.PersistableWithIdClassPK;
|
||||
import org.springframework.data.jpa.domain.sample.SampleEntity;
|
||||
@@ -43,6 +45,7 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
* @author Oliver Gierke
|
||||
* @author Thomas Darimont
|
||||
* @author Jens Schauder
|
||||
* @author Greg Turnquist
|
||||
*/
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@ContextConfiguration({ "classpath:infrastructure.xml" })
|
||||
@@ -128,6 +131,35 @@ class JpaRepositoryTests {
|
||||
assertThat(repository.findAll()).containsExactly(two);
|
||||
}
|
||||
|
||||
@Test // GH-2242
|
||||
void deleteAllByIdInBatchShouldConvertAnIterableToACollection() {
|
||||
|
||||
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();
|
||||
|
||||
/**
|
||||
* Wrap a {@link List} inside an {@link Iterable} to verify that {@link SimpleJpaRepository} can properly convert a
|
||||
* pure {@link Iterable} to a {@link Collection}.
|
||||
**/
|
||||
Iterable<SampleEntityPK> ids = new Iterable<SampleEntityPK>() {
|
||||
|
||||
private List<SampleEntityPK> ids = Arrays.asList(new SampleEntityPK("one", "eins"),
|
||||
new SampleEntityPK("three", "drei"));
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Iterator<SampleEntityPK> iterator() {
|
||||
return ids.iterator();
|
||||
}
|
||||
};
|
||||
|
||||
repository.deleteAllByIdInBatch(ids);
|
||||
assertThat(repository.findAll()).containsExactly(two);
|
||||
}
|
||||
|
||||
private interface SampleEntityRepository extends JpaRepository<SampleEntity, SampleEntityPK> {
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user