Skip to content

Commit 75c9af5

Browse files
committed
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.
1 parent edf06a9 commit 75c9af5

File tree

3 files changed

+54
-6
lines changed

3 files changed

+54
-6
lines changed

src/main/java/org/springframework/data/jpa/repository/support/SimpleJpaRepository.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
import java.util.List;
2525
import java.util.Map;
2626
import java.util.Optional;
27+
import java.util.stream.Collectors;
28+
import java.util.stream.StreamSupport;
2729

2830
import javax.persistence.EntityManager;
2931
import javax.persistence.LockModeType;
@@ -234,7 +236,16 @@ public void deleteAllByIdInBatch(Iterable<ID> ids) {
234236
entityInformation.getIdAttribute().getName());
235237

236238
Query query = em.createQuery(queryString);
237-
query.setParameter("ids", ids);
239+
/**
240+
* Some JPA providers require {@code ids} to be a {@link Collection} so we must convert if it's not already.
241+
*/
242+
if (Collection.class.isInstance(ids)) {
243+
query.setParameter("ids", ids);
244+
} else {
245+
Collection<ID> idsCollection = StreamSupport.stream(ids.spliterator(), false)
246+
.collect(Collectors.toCollection(ArrayList::new));
247+
query.setParameter("ids", idsCollection);
248+
}
238249

239250
query.executeUpdate();
240251
}

src/test/java/org/springframework/data/jpa/repository/support/EclipseLinkJpaRepositoryTests.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,20 @@
2222
* Integration tests to execute {@link JpaRepositoryTests} against EclipseLink.
2323
*
2424
* @author Oliver Gierke
25+
* @author Greg Turnquist
2526
*/
2627
@ContextConfiguration("classpath:eclipselink.xml")
2728
class EclipseLinkJpaRepositoryTests extends JpaRepositoryTests {
2829

2930
@Override
30-
/**
31-
* Ignored until https://bugs.eclipse.org/bugs/show_bug.cgi?id=349477 is resolved.
32-
*/
31+
@Disabled("https://bugs.eclipse.org/bugs/show_bug.cgi?id=349477")
3332
void deleteAllByIdInBatch() {
34-
super.deleteAllByIdInBatch();
33+
// disabled
34+
}
35+
36+
@Override
37+
@Disabled("https://bugs.eclipse.org/bugs/show_bug.cgi?id=349477")
38+
void deleteAllByIdInBatchShouldConvertAnIterableToACollection() {
39+
// disabled
3540
}
3641
}

src/test/java/org/springframework/data/jpa/repository/support/JpaRepositoryTests.java

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,17 @@
1818
import static org.assertj.core.api.Assertions.*;
1919

2020
import java.util.Arrays;
21+
import java.util.Iterator;
22+
import java.util.List;
2123
import java.util.Optional;
2224

2325
import javax.persistence.EntityManager;
2426
import javax.persistence.PersistenceContext;
2527

28+
import org.jetbrains.annotations.NotNull;
2629
import org.junit.jupiter.api.BeforeEach;
2730
import org.junit.jupiter.api.Test;
2831
import org.junit.jupiter.api.extension.ExtendWith;
29-
3032
import org.springframework.data.jpa.domain.sample.PersistableWithIdClass;
3133
import org.springframework.data.jpa.domain.sample.PersistableWithIdClassPK;
3234
import org.springframework.data.jpa.domain.sample.SampleEntity;
@@ -43,6 +45,7 @@
4345
* @author Oliver Gierke
4446
* @author Thomas Darimont
4547
* @author Jens Schauder
48+
* @author Greg Turnquist
4649
*/
4750
@ExtendWith(SpringExtension.class)
4851
@ContextConfiguration({ "classpath:infrastructure.xml" })
@@ -127,6 +130,35 @@ void deleteAllByIdInBatch() {
127130
assertThat(repository.findAll()).containsExactly(two);
128131
}
129132

133+
@Test // GH-2242
134+
void deleteAllByIdInBatchShouldConvertAnIterableToACollection() {
135+
136+
SampleEntity one = new SampleEntity("one", "eins");
137+
SampleEntity two = new SampleEntity("two", "zwei");
138+
SampleEntity three = new SampleEntity("three", "drei");
139+
repository.saveAll(Arrays.asList(one, two, three));
140+
repository.flush();
141+
142+
/**
143+
* Wrap a {@link List} inside an {@link Iterable} to verify that {@link SimpleJpaRepository} can properly convert a
144+
* pure {@link Iterable} to a {@link Collection}.
145+
**/
146+
Iterable<SampleEntityPK> ids = new Iterable<SampleEntityPK>() {
147+
148+
private List<SampleEntityPK> ids = Arrays.asList(new SampleEntityPK("one", "eins"),
149+
new SampleEntityPK("three", "drei"));
150+
151+
@NotNull
152+
@Override
153+
public Iterator<SampleEntityPK> iterator() {
154+
return ids.iterator();
155+
}
156+
};
157+
158+
repository.deleteAllByIdInBatch(ids);
159+
assertThat(repository.findAll()).containsExactly(two);
160+
}
161+
130162
private interface SampleEntityRepository extends JpaRepository<SampleEntity, SampleEntityPK> {
131163

132164
}

0 commit comments

Comments
 (0)