From ddbc49643f93f7dc46862f23c53386b2bbeeb201 Mon Sep 17 00:00:00 2001 From: Jacob Botuck Date: Sun, 10 May 2020 16:46:59 -0500 Subject: [PATCH] DATAMONGO-2285 - Throw BulkOperationException instead of translated one when running bulk operations. Return BulkOperationException unless it is a writeConcernError in which case use existing behavior. --- .../core/MongoExceptionTranslator.java | 20 ++++++++-------- .../MongoExceptionTranslatorUnitTests.java | 24 +++++++++++++++++++ 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoExceptionTranslator.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoExceptionTranslator.java index e34950375..cf1a788c6 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoExceptionTranslator.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoExceptionTranslator.java @@ -29,6 +29,7 @@ import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.dao.InvalidDataAccessResourceUsageException; import org.springframework.dao.PermissionDeniedDataAccessException; import org.springframework.dao.support.PersistenceExceptionTranslator; +import org.springframework.data.mongodb.BulkOperationException; import org.springframework.data.mongodb.ClientSessionException; import org.springframework.data.mongodb.MongoTransactionException; import org.springframework.data.mongodb.UncategorizedMongoDbException; @@ -39,7 +40,6 @@ import org.springframework.util.ClassUtils; import com.mongodb.MongoBulkWriteException; import com.mongodb.MongoException; import com.mongodb.MongoServerException; -import com.mongodb.bulk.BulkWriteError; /** * Simple {@link PersistenceExceptionTranslator} for Mongo. Convert the given runtime exception to an appropriate @@ -49,6 +49,7 @@ import com.mongodb.bulk.BulkWriteError; * @author Oliver Gierke * @author Michal Vich * @author Christoph Strobl + * @author Jacob Botuck */ public class MongoExceptionTranslator implements PersistenceExceptionTranslator { @@ -63,7 +64,7 @@ public class MongoExceptionTranslator implements PersistenceExceptionTranslator Collections.singletonList("MongoInternalException")); private static final Set DATA_INTEGRITY_EXCEPTIONS = new HashSet<>( - Arrays.asList("WriteConcernException", "MongoWriteException", "MongoBulkWriteException")); + Arrays.asList("WriteConcernException", "MongoWriteException")); /* * (non-Javadoc) @@ -98,18 +99,17 @@ public class MongoExceptionTranslator implements PersistenceExceptionTranslator if (((MongoServerException) ex).getCode() == 11000) { return new DuplicateKeyException(ex.getMessage(), ex); } - if (ex instanceof MongoBulkWriteException) { - for (BulkWriteError x : ((MongoBulkWriteException) ex).getWriteErrors()) { - if (x.getCode() == 11000) { - return new DuplicateKeyException(ex.getMessage(), ex); - } - } - } } return new DataIntegrityViolationException(ex.getMessage(), ex); } - + if (ex instanceof MongoBulkWriteException) { + MongoBulkWriteException mongoBulkWriteException = (MongoBulkWriteException) ex; + if (mongoBulkWriteException.getWriteConcernError() != null) { + return new DataIntegrityViolationException(ex.getMessage(), ex); + } + return new BulkOperationException(ex.getMessage(), mongoBulkWriteException); + } // All other MongoExceptions if (ex instanceof MongoException) { diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoExceptionTranslatorUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoExceptionTranslatorUnitTests.java index 04cd781ac..e9241b81c 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoExceptionTranslatorUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoExceptionTranslatorUnitTests.java @@ -18,7 +18,12 @@ package org.springframework.data.mongodb.core; import static org.assertj.core.api.Assertions.*; import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.Arrays; +import com.mongodb.MongoBulkWriteException; +import com.mongodb.bulk.BulkWriteError; +import com.mongodb.bulk.WriteConcernError; import org.bson.BsonDocument; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -26,9 +31,11 @@ import org.junit.jupiter.api.Test; import org.springframework.core.NestedRuntimeException; import org.springframework.dao.DataAccessException; import org.springframework.dao.DataAccessResourceFailureException; +import org.springframework.dao.DataIntegrityViolationException; import org.springframework.dao.DuplicateKeyException; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.dao.InvalidDataAccessResourceUsageException; +import org.springframework.data.mongodb.BulkOperationException; import org.springframework.data.mongodb.ClientSessionException; import org.springframework.data.mongodb.MongoTransactionException; import org.springframework.data.mongodb.UncategorizedMongoDbException; @@ -45,6 +52,7 @@ import com.mongodb.ServerAddress; * @author Michal Vich * @author Oliver Gierke * @author Christoph Strobl + * @author Jacob Botuck */ public class MongoExceptionTranslatorUnitTests { @@ -152,6 +160,22 @@ public class MongoExceptionTranslatorUnitTests { checkTranslatedMongoException(MongoTransactionException.class, 267); } + @Test + public void translateMongoBulkOperationExceptionWithWriteConcernError() { + + expectExceptionWithCauseMessage(translator.translateExceptionIfPossible(new MongoBulkWriteException(null, + new ArrayList<>(), new WriteConcernError(42, "codename", "writeconcern error happened", new BsonDocument()), + new ServerAddress())), DataIntegrityViolationException.class, null); + } + + @Test + public void translateMongoBulkOperationExceptionWithoutWriteConcernError() { + + expectExceptionWithCauseMessage(translator.translateExceptionIfPossible(new MongoBulkWriteException(null, + Arrays.asList(new BulkWriteError(42, "a write error happened", new BsonDocument(), 49)), null, + new ServerAddress())), BulkOperationException.class, null); + } + private void checkTranslatedMongoException(Class clazz, int code) { DataAccessException translated = translator.translateExceptionIfPossible(new MongoException(code, ""));