Handle list argument for findById, deletedById for DynamicInvocationHandler. (#1940)

Closes #1939.
This commit is contained in:
Michael Reiche
2024-05-06 16:06:04 -07:00
committed by GitHub
parent 33bf8c82cf
commit de2db4b7a2
5 changed files with 62 additions and 4 deletions

View File

@@ -110,7 +110,8 @@ public class DynamicInvocationHandler<T> implements InvocationHandler {
.map(o -> o == null ? null : (o.getClass() == entityInformation.getJavaType() ? Object.class : o.getClass()))
.toArray(Class<?>[]::new);
// the CouchbaseRepository methods - findById(id) etc - will have a parameter type of Object instead of ID
if (method.getName().endsWith("ById") && args.length == 1) {
// but deleteByAllId first parameter will be an iterable.
if (method.getName().endsWith("ById") && args.length == 1 && ! Iterable.class.isAssignableFrom(paramTypes[0]) ) {
paramTypes[0] = Object.class;
}
}

View File

@@ -73,7 +73,7 @@ public class SimpleCouchbaseRepository<T, ID> extends CouchbaseRepositoryBase<T,
String scopeName = getScope();
String collectionName = getCollection();
// clear out the PseudoArgs here as whatever is called by operations.save() could be in a different thread.
// not that this will also clear out Options, but that's ok as any options would not work
// note that this will also clear out Options, but that's ok as any options would not work
// with all of insert/upsert/replace. If Options are needed, use template.insertById/upsertById/replaceById
getReactiveTemplate().setPseudoArgs(null);
return operations.save(entity, scopeName, collectionName);
@@ -82,7 +82,13 @@ public class SimpleCouchbaseRepository<T, ID> extends CouchbaseRepositoryBase<T,
@Override
public <S extends T> Iterable<S> saveAll(Iterable<S> entities) {
Assert.notNull(entities, "The given Iterable of entities must not be null!");
return Streamable.of(entities).stream().map((e) -> save(e)).collect(StreamUtils.toUnmodifiableList());
String scopeName = getScope();
String collectionName = getCollection();
// clear out the PseudoArgs here as whatever is called by operations.save() could be in a different thread.
// note that this will also clear out Options, but that's ok as any options would not work
// with all of insert/upsert/replace. If Options are needed, use template.insertById/upsertById/replaceById
getReactiveTemplate().setPseudoArgs(null);
return Streamable.of(entities).stream().map((e) -> operations.save(e,scopeName, collectionName)).collect(StreamUtils.toUnmodifiableList());
}
@Override

View File

@@ -77,7 +77,7 @@ public class SimpleReactiveCouchbaseRepository<T, ID> extends CouchbaseRepositor
String scopeName = getScope();
String collectionName = getCollection();
// clear out the PseudoArgs here as whatever is called by operations.save() could be in a different thread.
// not that this will also clear out Options, but that's ok as any options would not work
// note that this will also clear out Options, but that's ok as any options would not work
// with all of insert/upsert/replace. If Options are needed, use template.insertById/upsertById/replaceById
getReactiveTemplate().setPseudoArgs(null);
return operations.save(entity, scopeName, collectionName);
@@ -88,6 +88,10 @@ public class SimpleReactiveCouchbaseRepository<T, ID> extends CouchbaseRepositor
Assert.notNull(entities, "The given Iterable of entities must not be null!");
String scope = getScope();
String collection = getCollection();
// clear out the PseudoArgs here as whatever is called by operations.save() could be in a different thread.
// note that this will also clear out Options, but that's ok as any options would not work
// with all of insert/upsert/replace. If Options are needed, use template.insertById/upsertById/replaceById
getReactiveTemplate().setPseudoArgs(null);
return Flux.fromIterable(entities).flatMap(e -> save(e, scope, collection));
}
@@ -96,6 +100,10 @@ public class SimpleReactiveCouchbaseRepository<T, ID> extends CouchbaseRepositor
Assert.notNull(entityStream, "The given Iterable of entities must not be null!");
String scope = getScope();
String collection = getCollection();
// clear out the PseudoArgs here as whatever is called by operations.save() could be in a different thread.
// note that this will also clear out Options, but that's ok as any options would not work
// with all of insert/upsert/replace. If Options are needed, use template.insertById/upsertById/replaceById
getReactiveTemplate().setPseudoArgs(null);
return Flux.from(entityStream).flatMap(e -> save(e, scope, collection));
}

View File

@@ -17,6 +17,8 @@ package org.springframework.data.couchbase.repository.query;
import static com.couchbase.client.core.io.CollectionIdentifier.DEFAULT_SCOPE;
import static com.couchbase.client.java.query.QueryScanConsistency.REQUEST_PLUS;
import static java.util.Arrays.asList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
@@ -443,4 +445,23 @@ public class CouchbaseRepositoryQueryCollectionIntegrationTests extends Collecti
}
}
@Test // DATACOUCH-650, SDC-1939
void deleteAllById() {
Airport vienna = new Airport("airports::vie", "vie", "LOWW");
Airport frankfurt = new Airport("airports::fra", "fra", "EDDZ");
Airport losAngeles = new Airport("airports::lax", "lax", "KLAX");
AirportRepository ar = airportRepository.withScope(scopeName).withCollection(collectionName);
try {
ar.saveAll(asList(vienna, frankfurt, losAngeles));
List<Airport> airports = ar.findAllById(asList(vienna.getId(), losAngeles.getId()));
assertEquals(2, airports.size());
ar.deleteAllById(asList(vienna.getId(), losAngeles.getId()));
assertThat(ar.findAll()).containsExactly(frankfurt);
ar.deleteAll(asList(frankfurt));
} finally {
ar.deleteAll();
}
}
}

View File

@@ -15,9 +15,12 @@
*/
package org.springframework.data.couchbase.repository.query;
import static java.util.Arrays.asList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import org.springframework.data.couchbase.domain.AirportRepository;
import reactor.core.Disposable;
import java.util.List;
@@ -298,4 +301,23 @@ public class ReactiveCouchbaseRepositoryQueryCollectionIntegrationTests extends
}
}
@Test // DATACOUCH-650, SDC-1939
void deleteAllById() {
Airport vienna = new Airport("airports::vie", "vie", "LOWW");
Airport frankfurt = new Airport("airports::fra", "fra", "EDDZ");
Airport losAngeles = new Airport("airports::lax", "lax", "KLAX");
ReactiveAirportRepository ar = reactiveAirportRepository.withScope(scopeName).withCollection(collectionName);
try {
ar.saveAll(asList(vienna, frankfurt, losAngeles)).blockLast();
List<Airport> airports = ar.findAllById(asList(vienna.getId(), losAngeles.getId())).collectList().block();
assertEquals(2, airports.size());
ar.deleteAllById(asList(vienna.getId(), losAngeles.getId())).block();
assertThat(ar.findAll().collectList().block()).containsExactly(frankfurt);
ar.deleteAll(asList(frankfurt)).block();
} finally {
ar.deleteAll().block();
}
}
}