Skip to content

Commit 3dd86c1

Browse files
committed
Allow configuration of ExceptionTranslator in MongoDatabaseFactorySupport.
1 parent c0b82fc commit 3dd86c1

File tree

7 files changed

+73
-63
lines changed

7 files changed

+73
-63
lines changed

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoClientFactoryBean.java

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -55,16 +55,14 @@
5555
*/
5656
public class MongoClientFactoryBean extends AbstractFactoryBean<MongoClient> implements PersistenceExceptionTranslator {
5757

58-
private static final PersistenceExceptionTranslator DEFAULT_EXCEPTION_TRANSLATOR = new MongoExceptionTranslator();
59-
6058
private @Nullable MongoClientSettings mongoClientSettings;
6159
private @Nullable String host;
6260
private @Nullable Integer port;
6361
private @Nullable List<MongoCredential> credential = null;
6462
private @Nullable ConnectionString connectionString;
6563
private @Nullable String replicaSet = null;
6664

67-
private PersistenceExceptionTranslator exceptionTranslator = DEFAULT_EXCEPTION_TRANSLATOR;
65+
private PersistenceExceptionTranslator exceptionTranslator = MongoExceptionTranslator.DEFAULT_EXCEPTION_TRANSLATOR;
6866

6967
/**
7068
* Set the {@link MongoClientSettings} to be used when creating {@link MongoClient}.
@@ -116,23 +114,34 @@ public void setReplicaSet(@Nullable String replicaSet) {
116114
* @param exceptionTranslator
117115
*/
118116
public void setExceptionTranslator(@Nullable PersistenceExceptionTranslator exceptionTranslator) {
119-
this.exceptionTranslator = exceptionTranslator == null ? DEFAULT_EXCEPTION_TRANSLATOR : exceptionTranslator;
120-
}
121-
122-
public Class<? extends MongoClient> getObjectType() {
123-
return MongoClient.class;
117+
this.exceptionTranslator = exceptionTranslator == null ? MongoExceptionTranslator.DEFAULT_EXCEPTION_TRANSLATOR
118+
: exceptionTranslator;
124119
}
125120

121+
@Override
126122
@Nullable
127123
public DataAccessException translateExceptionIfPossible(RuntimeException ex) {
128124
return exceptionTranslator.translateExceptionIfPossible(ex);
129125
}
130126

127+
@Override
128+
public Class<? extends MongoClient> getObjectType() {
129+
return MongoClient.class;
130+
}
131+
131132
@Override
132133
protected MongoClient createInstance() throws Exception {
133134
return createMongoClient(computeClientSetting());
134135
}
135136

137+
@Override
138+
protected void destroyInstance(@Nullable MongoClient instance) throws Exception {
139+
140+
if (instance != null) {
141+
instance.close();
142+
}
143+
}
144+
136145
/**
137146
* Create {@link MongoClientSettings} based on configuration and priority (lower is better).
138147
* <ol>
@@ -324,14 +333,6 @@ private <T> T computeSettingsValue(T defaultValue, T fromSettings, T fromConnect
324333
return !fromConnectionStringIsDefault ? fromConnectionString : defaultValue;
325334
}
326335

327-
@Override
328-
protected void destroyInstance(@Nullable MongoClient instance) throws Exception {
329-
330-
if (instance != null) {
331-
instance.close();
332-
}
333-
}
334-
335336
private MongoClient createMongoClient(MongoClientSettings settings) throws UnknownHostException {
336337
return MongoClients.create(settings, SpringDataMongoDB.driverInformation());
337338
}

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoDatabaseFactorySupport.java

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,7 @@
3232

3333
/**
3434
* Common base class for usage with both {@link com.mongodb.client.MongoClients} defining common properties such as
35-
* database name and exception translator.
36-
* <br />
35+
* database name and exception translator. <br />
3736
* Not intended to be used directly.
3837
*
3938
* @author Christoph Strobl
@@ -47,8 +46,8 @@ public abstract class MongoDatabaseFactorySupport<C> implements MongoDatabaseFac
4746
private final C mongoClient;
4847
private final String databaseName;
4948
private final boolean mongoInstanceCreated;
50-
private final PersistenceExceptionTranslator exceptionTranslator;
5149

50+
private PersistenceExceptionTranslator exceptionTranslator;
5251
private @Nullable WriteConcern writeConcern;
5352

5453
/**
@@ -75,15 +74,31 @@ protected MongoDatabaseFactorySupport(C mongoClient, String databaseName, boolea
7574
this.exceptionTranslator = exceptionTranslator;
7675
}
7776

77+
/**
78+
* Configures the {@link PersistenceExceptionTranslator} to be used.
79+
*
80+
* @param exceptionTranslator the exception translator to set.
81+
* @since 4.4
82+
*/
83+
public void setExceptionTranslator(PersistenceExceptionTranslator exceptionTranslator) {
84+
this.exceptionTranslator = exceptionTranslator;
85+
}
86+
87+
@Override
88+
public PersistenceExceptionTranslator getExceptionTranslator() {
89+
return this.exceptionTranslator;
90+
}
91+
7892
/**
7993
* Configures the {@link WriteConcern} to be used on the {@link MongoDatabase} instance being created.
8094
*
81-
* @param writeConcern the writeConcern to set
95+
* @param writeConcern the writeConcern to set.
8296
*/
8397
public void setWriteConcern(WriteConcern writeConcern) {
8498
this.writeConcern = writeConcern;
8599
}
86100

101+
@Override
87102
public MongoDatabase getMongoDatabase() throws DataAccessException {
88103
return getMongoDatabase(getDefaultDatabaseName());
89104
}
@@ -116,10 +131,7 @@ public void destroy() throws Exception {
116131
}
117132
}
118133

119-
public PersistenceExceptionTranslator getExceptionTranslator() {
120-
return this.exceptionTranslator;
121-
}
122-
134+
@Override
123135
public MongoDatabaseFactory withSession(ClientSession session) {
124136
return new MongoDatabaseFactorySupport.ClientSessionBoundMongoDbFactory(session, this);
125137
}

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoExceptionTranslator.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@
5252
*/
5353
public class MongoExceptionTranslator implements PersistenceExceptionTranslator {
5454

55+
public static final MongoExceptionTranslator DEFAULT_EXCEPTION_TRANSLATOR = new MongoExceptionTranslator();
56+
5557
private static final Set<String> DUPLICATE_KEY_EXCEPTIONS = Set.of("MongoException.DuplicateKey",
5658
"DuplicateKeyException");
5759

@@ -183,12 +185,10 @@ DataAccessException doTranslateException(RuntimeException ex) {
183185
*/
184186
public boolean isTransientFailure(Exception e) {
185187

186-
if (!(e instanceof MongoException)) {
188+
if (!(e instanceof MongoException mongoException)) {
187189
return false;
188190
}
189191

190-
MongoException mongoException = (MongoException) e;
191-
192192
return mongoException.hasErrorLabel(MongoException.TRANSIENT_TRANSACTION_ERROR_LABEL)
193193
|| mongoException.hasErrorLabel(MongoException.UNKNOWN_TRANSACTION_COMMIT_RESULT_LABEL);
194194
}

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMongoClientFactoryBean.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,11 @@
3636
public class ReactiveMongoClientFactoryBean extends AbstractFactoryBean<MongoClient>
3737
implements PersistenceExceptionTranslator {
3838

39-
private static final PersistenceExceptionTranslator DEFAULT_EXCEPTION_TRANSLATOR = new MongoExceptionTranslator();
40-
4139
private @Nullable String connectionString;
4240
private @Nullable String host;
4341
private @Nullable Integer port;
4442
private @Nullable MongoClientSettings mongoClientSettings;
45-
private PersistenceExceptionTranslator exceptionTranslator = DEFAULT_EXCEPTION_TRANSLATOR;
43+
private PersistenceExceptionTranslator exceptionTranslator = MongoExceptionTranslator.DEFAULT_EXCEPTION_TRANSLATOR;
4644

4745
/**
4846
* Configures the host to connect to.
@@ -86,7 +84,13 @@ public void setMongoClientSettings(@Nullable MongoClientSettings mongoClientSett
8684
* @param exceptionTranslator
8785
*/
8886
public void setExceptionTranslator(@Nullable PersistenceExceptionTranslator exceptionTranslator) {
89-
this.exceptionTranslator = exceptionTranslator == null ? DEFAULT_EXCEPTION_TRANSLATOR : exceptionTranslator;
87+
this.exceptionTranslator = exceptionTranslator == null ? MongoExceptionTranslator.DEFAULT_EXCEPTION_TRANSLATOR
88+
: exceptionTranslator;
89+
}
90+
91+
@Override
92+
public DataAccessException translateExceptionIfPossible(RuntimeException ex) {
93+
return exceptionTranslator.translateExceptionIfPossible(ex);
9094
}
9195

9296
@Override
@@ -123,8 +127,4 @@ protected void destroyInstance(@Nullable MongoClient instance) throws Exception
123127
instance.close();
124128
}
125129

126-
@Override
127-
public DataAccessException translateExceptionIfPossible(RuntimeException ex) {
128-
return exceptionTranslator.translateExceptionIfPossible(ex);
129-
}
130130
}

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/SimpleMongoClientDatabaseFactory.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ public SimpleMongoClientDatabaseFactory(MongoClient mongoClient, String database
7272
* @param mongoInstanceCreated
7373
*/
7474
SimpleMongoClientDatabaseFactory(MongoClient mongoClient, String databaseName, boolean mongoInstanceCreated) {
75-
super(mongoClient, databaseName, mongoInstanceCreated, new MongoExceptionTranslator());
75+
super(mongoClient, databaseName, mongoInstanceCreated, MongoExceptionTranslator.DEFAULT_EXCEPTION_TRANSLATOR);
7676
}
7777

7878
@Override

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/SimpleReactiveMongoDatabaseFactory.java

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,7 @@ public class SimpleReactiveMongoDatabaseFactory implements DisposableBean, React
5151
private final String databaseName;
5252
private final boolean mongoInstanceCreated;
5353

54-
private final PersistenceExceptionTranslator exceptionTranslator;
55-
54+
private PersistenceExceptionTranslator exceptionTranslator = MongoExceptionTranslator.DEFAULT_EXCEPTION_TRANSLATOR;
5655
private @Nullable WriteConcern writeConcern;
5756

5857
/**
@@ -85,7 +84,21 @@ private SimpleReactiveMongoDatabaseFactory(MongoClient client, String databaseNa
8584
this.mongo = client;
8685
this.databaseName = databaseName;
8786
this.mongoInstanceCreated = mongoInstanceCreated;
88-
this.exceptionTranslator = new MongoExceptionTranslator();
87+
}
88+
89+
/**
90+
* Configures the {@link PersistenceExceptionTranslator} to be used.
91+
*
92+
* @param exceptionTranslator the exception translator to set.
93+
* @since 4.4
94+
*/
95+
public void setExceptionTranslator(PersistenceExceptionTranslator exceptionTranslator) {
96+
this.exceptionTranslator = exceptionTranslator;
97+
}
98+
99+
@Override
100+
public PersistenceExceptionTranslator getExceptionTranslator() {
101+
return this.exceptionTranslator;
89102
}
90103

91104
/**
@@ -97,10 +110,12 @@ public void setWriteConcern(WriteConcern writeConcern) {
97110
this.writeConcern = writeConcern;
98111
}
99112

113+
@Override
100114
public Mono<MongoDatabase> getMongoDatabase() throws DataAccessException {
101115
return getMongoDatabase(databaseName);
102116
}
103117

118+
@Override
104119
public Mono<MongoDatabase> getMongoDatabase(String dbName) throws DataAccessException {
105120

106121
Assert.hasText(dbName, "Database name must not be empty");
@@ -118,17 +133,14 @@ public Mono<MongoDatabase> getMongoDatabase(String dbName) throws DataAccessExce
118133
*
119134
* @see DisposableBean#destroy()
120135
*/
136+
@Override
121137
public void destroy() throws Exception {
122138

123139
if (mongoInstanceCreated) {
124140
mongo.close();
125141
}
126142
}
127143

128-
public PersistenceExceptionTranslator getExceptionTranslator() {
129-
return this.exceptionTranslator;
130-
}
131-
132144
@Override
133145
public CodecRegistry getCodecRegistry() {
134146
return this.mongo.getDatabase(databaseName).getCodecRegistry();

spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoExceptionTranslatorUnitTests.java

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,16 @@
2020
import org.bson.BsonDocument;
2121
import org.junit.jupiter.api.BeforeEach;
2222
import org.junit.jupiter.api.Test;
23-
2423
import org.mockito.Mockito;
24+
2525
import org.springframework.core.NestedRuntimeException;
2626
import org.springframework.dao.DataAccessException;
2727
import org.springframework.dao.DataAccessResourceFailureException;
28-
import org.springframework.dao.DataIntegrityViolationException;
2928
import org.springframework.dao.DuplicateKeyException;
3029
import org.springframework.dao.InvalidDataAccessApiUsageException;
3130
import org.springframework.dao.InvalidDataAccessResourceUsageException;
3231
import org.springframework.data.mongodb.ClientSessionException;
3332
import org.springframework.data.mongodb.MongoTransactionException;
34-
import org.springframework.data.mongodb.TransientMongoDbException;
3533
import org.springframework.data.mongodb.UncategorizedMongoDbException;
3634
import org.springframework.lang.Nullable;
3735

@@ -41,9 +39,7 @@
4139
import com.mongodb.MongoSocketException;
4240
import com.mongodb.MongoSocketReadTimeoutException;
4341
import com.mongodb.MongoSocketWriteException;
44-
import com.mongodb.MongoWriteException;
4542
import com.mongodb.ServerAddress;
46-
import com.mongodb.WriteError;
4743

4844
/**
4945
* Unit tests for {@link MongoExceptionTranslator}.
@@ -180,30 +176,19 @@ public void translateTransientTransactionExceptions() {
180176
MongoException source = new MongoException(267, "PreparedTransactionInProgress");
181177
source.addLabel(MongoException.TRANSIENT_TRANSACTION_ERROR_LABEL);
182178

183-
expectExceptionWithCauseMessage(translator.translateExceptionIfPossible(source), TransientMongoDbException.class,
179+
expectExceptionWithCauseMessage(translator.translateExceptionIfPossible(source),
180+
UncategorizedMongoDbException.class,
184181
"PreparedTransactionInProgress");
185182
}
186183

187184
@Test // DATAMONGO-2073
188-
public void translateMongoExceptionWithTransientLabelToTransientMongoDbException() {
185+
public void translateMongoExceptionWithTransientLabel() {
189186

190187
MongoException exception = new MongoException(0, "");
191188
exception.addLabel(MongoException.UNKNOWN_TRANSACTION_COMMIT_RESULT_LABEL);
192189
DataAccessException translatedException = translator.translateExceptionIfPossible(exception);
193190

194-
expectExceptionWithCauseMessage(translatedException, TransientMongoDbException.class);
195-
}
196-
197-
@Test // DATAMONGO-2073
198-
public void wrapsTranslatedExceptionsWhenTransientLabelPresent() {
199-
200-
MongoException exception = new MongoWriteException(new WriteError(112, "WriteConflict", new BsonDocument()), null);
201-
exception.addLabel(MongoException.UNKNOWN_TRANSACTION_COMMIT_RESULT_LABEL);
202-
203-
DataAccessException translatedException = translator.translateExceptionIfPossible(exception);
204-
205-
assertThat(translatedException).isInstanceOf(TransientMongoDbException.class);
206-
assertThat(translatedException.getCause()).isInstanceOf(DataIntegrityViolationException.class);
191+
expectExceptionWithCauseMessage(translatedException, UncategorizedMongoDbException.class);
207192
}
208193

209194
private void checkTranslatedMongoException(Class<? extends Exception> clazz, int code) {

0 commit comments

Comments
 (0)