Skip to content

Commit 7fbd496

Browse files
committed
Polishing.
Original pull request: spring-projects#605 See spring-projects#3148 See spring-projects#2939
1 parent dced760 commit 7fbd496

11 files changed

+148
-130
lines changed

Diff for: spring-data-mongodb/src/main/java/org/springframework/data/mongodb/TransientClientSessionException.java

+4-5
Original file line numberDiff line numberDiff line change
@@ -16,24 +16,23 @@
1616
package org.springframework.data.mongodb;
1717

1818
import org.springframework.dao.TransientDataAccessException;
19-
import org.springframework.lang.Nullable;
2019

2120
/**
2221
* {@link TransientDataAccessException} specific to MongoDB {@link com.mongodb.session.ClientSession} related data
2322
* access failures such as reading data using an already closed session.
2423
*
2524
* @author Christoph Strobl
26-
* @since 3.3
25+
* @since 4.4
2726
*/
2827
public class TransientClientSessionException extends TransientMongoDbException {
2928

3029
/**
3130
* Constructor for {@link TransientClientSessionException}.
3231
*
33-
* @param msg the detail message. Can be {@literal null}.
34-
* @param cause the root cause. Can be {@literal null}.
32+
* @param msg the detail message.
33+
* @param cause the root cause.
3534
*/
36-
public TransientClientSessionException(@Nullable String msg, @Nullable Throwable cause) {
35+
public TransientClientSessionException(String msg, Throwable cause) {
3736
super(msg, cause);
3837
}
3938
}

Diff for: spring-data-mongodb/src/main/java/org/springframework/data/mongodb/TransientMongoDbException.java

+4-5
Original file line numberDiff line numberDiff line change
@@ -16,25 +16,24 @@
1616
package org.springframework.data.mongodb;
1717

1818
import org.springframework.dao.TransientDataAccessException;
19-
import org.springframework.lang.Nullable;
2019

2120
/**
2221
* Root of the hierarchy of MongoDB specific data access exceptions that are considered transient such as
2322
* {@link com.mongodb.MongoException MongoExceptions} carrying {@link com.mongodb.MongoException#hasErrorLabel(String)
2423
* specific labels}.
2524
*
2625
* @author Christoph Strobl
27-
* @since 3.3
26+
* @since 4.4
2827
*/
2928
public class TransientMongoDbException extends TransientDataAccessException {
3029

3130
/**
3231
* Constructor for {@link TransientMongoDbException}.
3332
*
34-
* @param msg the detail message. Can be {@literal null}.
35-
* @param cause the root cause. Can be {@literal null}.
33+
* @param msg the detail message.
34+
* @param cause the root cause.
3635
*/
37-
public TransientMongoDbException(String msg, @Nullable Throwable cause) {
36+
public TransientMongoDbException(String msg, Throwable cause) {
3837
super(msg, cause);
3938
}
4039
}

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

+17-16
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
}

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

+20-8
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
}

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

+14-22
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,17 @@
1818
import java.util.Set;
1919

2020
import org.bson.BsonInvalidOperationException;
21+
2122
import org.springframework.dao.DataAccessException;
2223
import org.springframework.dao.DataAccessResourceFailureException;
2324
import org.springframework.dao.DataIntegrityViolationException;
2425
import org.springframework.dao.DuplicateKeyException;
2526
import org.springframework.dao.InvalidDataAccessApiUsageException;
2627
import org.springframework.dao.InvalidDataAccessResourceUsageException;
2728
import org.springframework.dao.PermissionDeniedDataAccessException;
28-
import org.springframework.dao.TransientDataAccessException;
2929
import org.springframework.dao.support.PersistenceExceptionTranslator;
3030
import org.springframework.data.mongodb.ClientSessionException;
3131
import org.springframework.data.mongodb.TransientClientSessionException;
32-
import org.springframework.data.mongodb.TransientMongoDbException;
3332
import org.springframework.data.mongodb.UncategorizedMongoDbException;
3433
import org.springframework.data.mongodb.util.MongoDbErrorCodes;
3534
import org.springframework.lang.Nullable;
@@ -53,6 +52,8 @@
5352
*/
5453
public class MongoExceptionTranslator implements PersistenceExceptionTranslator {
5554

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

@@ -70,18 +71,7 @@ public class MongoExceptionTranslator implements PersistenceExceptionTranslator
7071
@Override
7172
@Nullable
7273
public DataAccessException translateExceptionIfPossible(RuntimeException ex) {
73-
74-
DataAccessException translatedException = doTranslateException(ex);
75-
if (translatedException == null) {
76-
return null;
77-
}
78-
79-
// Translated exceptions that per se are not be recoverable (eg. WriteConflicts), might still be transient inside a
80-
// transaction. Let's wrap those.
81-
return (isTransientFailure(ex) && !(translatedException instanceof TransientDataAccessException))
82-
? new TransientMongoDbException(ex.getMessage(), translatedException)
83-
: translatedException;
84-
74+
return doTranslateException(ex);
8575
}
8676

8777
@Nullable
@@ -180,21 +170,23 @@ DataAccessException doTranslateException(RuntimeException ex) {
180170
/**
181171
* Check if a given exception holds an error label indicating a transient failure.
182172
*
183-
* @param e
173+
* @param e the exception to inspect.
184174
* @return {@literal true} if the given {@link Exception} is a {@link MongoException} holding one of the transient
185175
* exception error labels.
186176
* @see MongoException#hasErrorLabel(String)
187-
* @since 3.3
177+
* @since 4.4
188178
*/
189-
public static boolean isTransientFailure(Exception e) {
179+
public boolean isTransientFailure(Exception e) {
190180

191-
if (!(e instanceof MongoException)) {
192-
return false;
181+
if (e instanceof MongoException mongoException) {
182+
return mongoException.hasErrorLabel(MongoException.TRANSIENT_TRANSACTION_ERROR_LABEL)
183+
|| mongoException.hasErrorLabel(MongoException.UNKNOWN_TRANSACTION_COMMIT_RESULT_LABEL);
193184
}
194185

195-
MongoException mongoException = (MongoException) e;
186+
if (e.getCause() != e && e.getCause() instanceof Exception ex) {
187+
return isTransientFailure(ex);
188+
}
196189

197-
return mongoException.hasErrorLabel(MongoException.TRANSIENT_TRANSACTION_ERROR_LABEL)
198-
|| mongoException.hasErrorLabel(MongoException.UNKNOWN_TRANSACTION_COMMIT_RESULT_LABEL);
190+
return false;
199191
}
200192
}

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

+8-8
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
}

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

+1-1
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

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

+19-7
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();

0 commit comments

Comments
 (0)