Compare commits
3 Commits
4.0.x
...
issue/DATA
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
28191fd505 | ||
|
|
ddbc49643f | ||
|
|
c91d18c113 |
2
pom.xml
2
pom.xml
@@ -5,7 +5,7 @@
|
||||
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>3.1.0-SNAPSHOT</version>
|
||||
<version>3.1.0-DATAMONGO-2285-SNAPSHOT</version>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<name>Spring Data MongoDB</name>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>3.1.0-SNAPSHOT</version>
|
||||
<version>3.1.0-DATAMONGO-2285-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>3.1.0-SNAPSHOT</version>
|
||||
<version>3.1.0-DATAMONGO-2285-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>3.1.0-SNAPSHOT</version>
|
||||
<version>3.1.0-DATAMONGO-2285-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -24,8 +24,9 @@ import java.util.stream.Collectors;
|
||||
import org.bson.Document;
|
||||
import org.bson.conversions.Bson;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.dao.support.PersistenceExceptionTranslator;
|
||||
import org.springframework.dao.DataIntegrityViolationException;
|
||||
import org.springframework.data.mapping.callback.EntityCallbacks;
|
||||
import org.springframework.data.mongodb.BulkOperationException;
|
||||
import org.springframework.data.mongodb.core.convert.QueryMapper;
|
||||
import org.springframework.data.mongodb.core.convert.UpdateMapper;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
|
||||
@@ -46,6 +47,7 @@ import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
import com.mongodb.MongoBulkWriteException;
|
||||
import com.mongodb.WriteConcern;
|
||||
import com.mongodb.bulk.BulkWriteResult;
|
||||
import com.mongodb.client.MongoCollection;
|
||||
@@ -62,6 +64,7 @@ import com.mongodb.client.model.*;
|
||||
* @author Jens Schauder
|
||||
* @author Michail Nikolaev
|
||||
* @author Roman Puchkovskiy
|
||||
* @author Jacob Botuck
|
||||
* @since 1.9
|
||||
*/
|
||||
class DefaultBulkOperations implements BulkOperations {
|
||||
@@ -71,7 +74,6 @@ class DefaultBulkOperations implements BulkOperations {
|
||||
private final BulkOperationContext bulkOperationContext;
|
||||
private final List<SourceAwareWriteModelHolder> models = new ArrayList<>();
|
||||
|
||||
private PersistenceExceptionTranslator exceptionTranslator;
|
||||
private @Nullable WriteConcern defaultWriteConcern;
|
||||
|
||||
private BulkWriteOptions bulkOptions;
|
||||
@@ -95,19 +97,9 @@ class DefaultBulkOperations implements BulkOperations {
|
||||
this.mongoOperations = mongoOperations;
|
||||
this.collectionName = collectionName;
|
||||
this.bulkOperationContext = bulkOperationContext;
|
||||
this.exceptionTranslator = new MongoExceptionTranslator();
|
||||
this.bulkOptions = getBulkWriteOptions(bulkOperationContext.getBulkMode());
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the {@link PersistenceExceptionTranslator} to be used. Defaults to {@link MongoExceptionTranslator}.
|
||||
*
|
||||
* @param exceptionTranslator can be {@literal null}.
|
||||
*/
|
||||
public void setExceptionTranslator(@Nullable PersistenceExceptionTranslator exceptionTranslator) {
|
||||
this.exceptionTranslator = exceptionTranslator == null ? new MongoExceptionTranslator() : exceptionTranslator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the default {@link WriteConcern} to be used. Defaults to {@literal null}.
|
||||
*
|
||||
@@ -314,11 +306,25 @@ class DefaultBulkOperations implements BulkOperations {
|
||||
collection = collection.withWriteConcern(defaultWriteConcern);
|
||||
}
|
||||
|
||||
return collection.bulkWrite( //
|
||||
models.stream() //
|
||||
.map(this::extractAndMapWriteModel) //
|
||||
.collect(Collectors.toList()), //
|
||||
bulkOptions);
|
||||
try {
|
||||
return collection.bulkWrite( //
|
||||
models.stream() //
|
||||
.map(this::extractAndMapWriteModel) //
|
||||
.collect(Collectors.toList()), //
|
||||
bulkOptions);
|
||||
} catch (Exception ex) {
|
||||
|
||||
if (ex instanceof MongoBulkWriteException) {
|
||||
|
||||
MongoBulkWriteException mongoBulkWriteException = (MongoBulkWriteException) ex;
|
||||
if (mongoBulkWriteException.getWriteConcernError() != null) {
|
||||
throw new DataIntegrityViolationException(ex.getMessage(), ex);
|
||||
}
|
||||
throw new BulkOperationException(ex.getMessage(), mongoBulkWriteException);
|
||||
}
|
||||
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
private WriteModel<Document> extractAndMapWriteModel(SourceAwareWriteModelHolder it) {
|
||||
|
||||
@@ -757,7 +757,6 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
new BulkOperationContext(mode, Optional.ofNullable(getPersistentEntity(entityType)), queryMapper, updateMapper,
|
||||
eventPublisher, entityCallbacks));
|
||||
|
||||
operations.setExceptionTranslator(exceptionTranslator);
|
||||
operations.setDefaultWriteConcern(writeConcern);
|
||||
|
||||
return operations;
|
||||
|
||||
@@ -27,6 +27,7 @@ import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.springframework.dao.DuplicateKeyException;
|
||||
import org.springframework.data.mongodb.BulkOperationException;
|
||||
import org.springframework.data.mongodb.core.BulkOperations.BulkMode;
|
||||
import org.springframework.data.mongodb.core.DefaultBulkOperations.BulkOperationContext;
|
||||
import org.springframework.data.mongodb.core.convert.QueryMapper;
|
||||
@@ -91,13 +92,13 @@ public class DefaultBulkOperationsIntegrationTests {
|
||||
assertThat(createBulkOps(BulkMode.ORDERED).insert(documents).execute().getInsertedCount()).isEqualTo(2);
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-934
|
||||
@Test // DATAMONGO-934, DATAMONGO-2285
|
||||
public void insertOrderedFails() {
|
||||
|
||||
List<BaseDoc> documents = Arrays.asList(newDoc("1"), newDoc("1"), newDoc("2"));
|
||||
|
||||
assertThatThrownBy(() -> createBulkOps(BulkMode.ORDERED).insert(documents).execute()) //
|
||||
.isInstanceOf(DuplicateKeyException.class) //
|
||||
.isInstanceOf(BulkOperationException.class) //
|
||||
.hasCauseInstanceOf(MongoBulkWriteException.class) //
|
||||
.extracting(Throwable::getCause) //
|
||||
.satisfies(it -> {
|
||||
@@ -117,13 +118,13 @@ public class DefaultBulkOperationsIntegrationTests {
|
||||
assertThat(createBulkOps(BulkMode.UNORDERED).insert(documents).execute().getInsertedCount()).isEqualTo(2);
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-934
|
||||
@Test // DATAMONGO-934, DATAMONGO-2285
|
||||
public void insertUnOrderedContinuesOnError() {
|
||||
|
||||
List<BaseDoc> documents = Arrays.asList(newDoc("1"), newDoc("1"), newDoc("2"));
|
||||
|
||||
assertThatThrownBy(() -> createBulkOps(BulkMode.UNORDERED).insert(documents).execute()) //
|
||||
.isInstanceOf(DuplicateKeyException.class) //
|
||||
.isInstanceOf(BulkOperationException.class) //
|
||||
.hasCauseInstanceOf(MongoBulkWriteException.class) //
|
||||
.extracting(Throwable::getCause) //
|
||||
.satisfies(it -> {
|
||||
|
||||
@@ -24,6 +24,7 @@ import static org.mockito.Mockito.eq;
|
||||
import static org.springframework.data.mongodb.core.query.Criteria.*;
|
||||
import static org.springframework.data.mongodb.core.query.Query.*;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@@ -40,9 +41,11 @@ import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.dao.DataIntegrityViolationException;
|
||||
import org.springframework.dao.support.PersistenceExceptionTranslator;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.mapping.callback.EntityCallbacks;
|
||||
import org.springframework.data.mongodb.BulkOperationException;
|
||||
import org.springframework.data.mongodb.MongoDatabaseFactory;
|
||||
import org.springframework.data.mongodb.core.BulkOperations.BulkMode;
|
||||
import org.springframework.data.mongodb.core.DefaultBulkOperations.BulkOperationContext;
|
||||
@@ -64,9 +67,13 @@ import org.springframework.data.mongodb.core.query.Collation;
|
||||
import org.springframework.data.mongodb.core.query.Criteria;
|
||||
import org.springframework.data.mongodb.core.query.Update;
|
||||
|
||||
import com.mongodb.MongoBulkWriteException;
|
||||
import com.mongodb.MongoWriteException;
|
||||
import com.mongodb.ServerAddress;
|
||||
import com.mongodb.WriteConcern;
|
||||
import com.mongodb.WriteError;
|
||||
import com.mongodb.bulk.BulkWriteError;
|
||||
import com.mongodb.bulk.WriteConcernError;
|
||||
import com.mongodb.client.MongoCollection;
|
||||
import com.mongodb.client.MongoDatabase;
|
||||
import com.mongodb.client.model.BulkWriteOptions;
|
||||
@@ -85,6 +92,7 @@ import com.mongodb.client.model.WriteModel;
|
||||
* @author Minsu Kim
|
||||
* @author Jens Schauder
|
||||
* @author Roman Puchkovskiy
|
||||
* @author Jacob Botuck
|
||||
*/
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class DefaultBulkOperationsUnitTests {
|
||||
@@ -367,6 +375,29 @@ class DefaultBulkOperationsUnitTests {
|
||||
.isEqualTo(new Document("$set", new Document("items.$.documents.0.the_file_id", "file-id")));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2285
|
||||
public void translateMongoBulkOperationExceptionWithWriteConcernError() {
|
||||
|
||||
when(collection.bulkWrite(anyList(), any(BulkWriteOptions.class))).thenThrow(new MongoBulkWriteException(null,
|
||||
Collections.emptyList(),
|
||||
new WriteConcernError(42, "codename", "writeconcern error happened", new BsonDocument()), new ServerAddress()));
|
||||
|
||||
assertThatExceptionOfType(DataIntegrityViolationException.class)
|
||||
.isThrownBy(() -> ops.insert(new SomeDomainType()).execute());
|
||||
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2285
|
||||
public void translateMongoBulkOperationExceptionWithoutWriteConcernError() {
|
||||
|
||||
when(collection.bulkWrite(anyList(), any(BulkWriteOptions.class))).thenThrow(new MongoBulkWriteException(null,
|
||||
Collections.singletonList(new BulkWriteError(42, "a write error happened", new BsonDocument(), 49)), null,
|
||||
new ServerAddress()));
|
||||
|
||||
assertThatExceptionOfType(BulkOperationException.class)
|
||||
.isThrownBy(() -> ops.insert(new SomeDomainType()).execute());
|
||||
}
|
||||
|
||||
static class OrderTest {
|
||||
|
||||
String id;
|
||||
|
||||
Reference in New Issue
Block a user