diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/BindableMongoExpression.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/BindableMongoExpression.java
index 1f6875c080..3ae41aad35 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/BindableMongoExpression.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/BindableMongoExpression.java
@@ -20,9 +20,10 @@
import org.bson.Document;
import org.bson.codecs.DocumentCodec;
import org.bson.codecs.configuration.CodecRegistry;
+import org.jspecify.annotations.Nullable;
import org.springframework.data.mongodb.util.json.ParameterBindingDocumentCodec;
import org.springframework.data.util.Lazy;
-import org.springframework.lang.Nullable;
+import org.springframework.lang.Contract;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
@@ -31,8 +32,7 @@
* A {@link MongoExpression} using the {@link ParameterBindingDocumentCodec} for parsing a raw ({@literal json})
* expression. The expression will be wrapped within { ... }
if necessary. The actual parsing and parameter
* binding of placeholders like {@code ?0} is delayed upon first call on the target {@link Document} via
- * {@link #toDocument()}.
- *
+ * {@link #toDocument()}.
*
*
* $toUpper : $name -> { '$toUpper' : '$name' }
@@ -55,7 +55,7 @@ public class BindableMongoExpression implements MongoExpression {
private final @Nullable CodecRegistryProvider codecRegistryProvider;
- private final @Nullable Object[] args;
+ private final Object @Nullable [] args;
private final Lazy target;
@@ -63,9 +63,9 @@ public class BindableMongoExpression implements MongoExpression {
* Create a new instance of {@link BindableMongoExpression}.
*
* @param expression must not be {@literal null}.
- * @param args can be {@literal null}.
+ * @param args must not be {@literal null} but may contain {@literal null} elements.
*/
- public BindableMongoExpression(String expression, @Nullable Object[] args) {
+ public BindableMongoExpression(String expression, Object @Nullable [] args) {
this(expression, null, args);
}
@@ -74,10 +74,10 @@ public BindableMongoExpression(String expression, @Nullable Object[] args) {
*
* @param expression must not be {@literal null}.
* @param codecRegistryProvider can be {@literal null}.
- * @param args can be {@literal null}.
+ * @param args must not be {@literal null} but may contain {@literal null} elements.
*/
public BindableMongoExpression(String expression, @Nullable CodecRegistryProvider codecRegistryProvider,
- @Nullable Object[] args) {
+ Object @Nullable [] args) {
Assert.notNull(expression, "Expression must not be null");
@@ -93,6 +93,7 @@ public BindableMongoExpression(String expression, @Nullable CodecRegistryProvide
* @param codecRegistry must not be {@literal null}.
* @return new instance of {@link BindableMongoExpression}.
*/
+ @Contract("_ -> new")
public BindableMongoExpression withCodecRegistry(CodecRegistry codecRegistry) {
return new BindableMongoExpression(expressionString, () -> codecRegistry, args);
}
@@ -103,6 +104,7 @@ public BindableMongoExpression withCodecRegistry(CodecRegistry codecRegistry) {
* @param args must not be {@literal null}.
* @return new instance of {@link BindableMongoExpression}.
*/
+ @Contract("_ -> new")
public BindableMongoExpression bind(Object... args) {
return new BindableMongoExpression(expressionString, codecRegistryProvider, args);
}
@@ -139,7 +141,7 @@ private Document parse() {
private static String wrapJsonIfNecessary(String json) {
- if(!StringUtils.hasText(json)) {
+ if (!StringUtils.hasText(json)) {
return json;
}
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/BulkOperationException.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/BulkOperationException.java
index b36382a58e..12d8c966af 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/BulkOperationException.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/BulkOperationException.java
@@ -17,6 +17,7 @@
import java.util.List;
+import org.jspecify.annotations.Nullable;
import org.springframework.dao.DataAccessException;
import com.mongodb.MongoBulkWriteException;
@@ -40,10 +41,10 @@ public class BulkOperationException extends DataAccessException {
/**
* Creates a new {@link BulkOperationException} with the given message and source {@link MongoBulkWriteException}.
*
- * @param message must not be {@literal null}.
+ * @param message can be {@literal null}.
* @param source must not be {@literal null}.
*/
- public BulkOperationException(String message, MongoBulkWriteException source) {
+ public BulkOperationException(@Nullable String message, MongoBulkWriteException source) {
super(message, source);
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/ClientSessionException.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/ClientSessionException.java
index 53acf65470..c59eecb43a 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/ClientSessionException.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/ClientSessionException.java
@@ -15,8 +15,8 @@
*/
package org.springframework.data.mongodb;
+import org.jspecify.annotations.Nullable;
import org.springframework.dao.NonTransientDataAccessException;
-import org.springframework.lang.Nullable;
/**
* {@link NonTransientDataAccessException} specific to MongoDB {@link com.mongodb.session.ClientSession} related data
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/DefaultMongoTransactionOptionsResolver.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/DefaultMongoTransactionOptionsResolver.java
index c07e2dbe4a..87201ef9ee 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/DefaultMongoTransactionOptionsResolver.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/DefaultMongoTransactionOptionsResolver.java
@@ -18,7 +18,7 @@
import java.util.Map;
import java.util.Set;
-import org.springframework.lang.Nullable;
+import org.jspecify.annotations.Nullable;
/**
* Default implementation of {@link MongoTransactionOptions} using {@literal mongo:} as {@link #getLabelPrefix() label
@@ -42,9 +42,8 @@ public MongoTransactionOptions convert(Map options) {
return SimpleMongoTransactionOptions.of(options);
}
- @Nullable
@Override
- public String getLabelPrefix() {
+ public @Nullable String getLabelPrefix() {
return PREFIX;
}
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoDatabaseUtils.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoDatabaseUtils.java
index f73f9fb7ed..042a5ba1d3 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoDatabaseUtils.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoDatabaseUtils.java
@@ -15,7 +15,7 @@
*/
package org.springframework.data.mongodb;
-import org.springframework.lang.Nullable;
+import org.jspecify.annotations.Nullable;
import org.springframework.transaction.support.ResourceHolderSynchronization;
import org.springframework.transaction.support.TransactionSynchronization;
import org.springframework.transaction.support.TransactionSynchronizationManager;
@@ -29,8 +29,7 @@
/**
* Helper class for managing a {@link MongoDatabase} instances via {@link MongoDatabaseFactory}. Used for obtaining
* {@link ClientSession session bound} resources, such as {@link MongoDatabase} and
- * {@link com.mongodb.client.MongoCollection} suitable for transactional usage.
- *
+ * {@link com.mongodb.client.MongoCollection} suitable for transactional usage.
* Note: Intended for internal usage only.
*
* @author Christoph Strobl
@@ -42,8 +41,7 @@ public class MongoDatabaseUtils {
/**
* Obtain the default {@link MongoDatabase database} form the given {@link MongoDatabaseFactory factory} using
- * {@link SessionSynchronization#ON_ACTUAL_TRANSACTION native session synchronization}.
- *
+ * {@link SessionSynchronization#ON_ACTUAL_TRANSACTION native session synchronization}.
* Registers a {@link MongoSessionSynchronization MongoDB specific transaction synchronization} within the current
* {@link Thread} if {@link TransactionSynchronizationManager#isSynchronizationActive() synchronization is active}.
*
@@ -55,8 +53,7 @@ public static MongoDatabase getDatabase(MongoDatabaseFactory factory) {
}
/**
- * Obtain the default {@link MongoDatabase database} form the given {@link MongoDatabaseFactory factory}.
- *
+ * Obtain the default {@link MongoDatabase database} form the given {@link MongoDatabaseFactory factory}.
* Registers a {@link MongoSessionSynchronization MongoDB specific transaction synchronization} within the current
* {@link Thread} if {@link TransactionSynchronizationManager#isSynchronizationActive() synchronization is active}.
*
@@ -70,8 +67,7 @@ public static MongoDatabase getDatabase(MongoDatabaseFactory factory, SessionSyn
/**
* Obtain the {@link MongoDatabase database} with given name form the given {@link MongoDatabaseFactory factory} using
- * {@link SessionSynchronization#ON_ACTUAL_TRANSACTION native session synchronization}.
- *
+ * {@link SessionSynchronization#ON_ACTUAL_TRANSACTION native session synchronization}.
* Registers a {@link MongoSessionSynchronization MongoDB specific transaction synchronization} within the current
* {@link Thread} if {@link TransactionSynchronizationManager#isSynchronizationActive() synchronization is active}.
*
@@ -139,8 +135,7 @@ public static boolean isTransactionActive(MongoDatabaseFactory dbFactory) {
return resourceHolder != null && resourceHolder.hasActiveTransaction();
}
- @Nullable
- private static ClientSession doGetSession(MongoDatabaseFactory dbFactory,
+ private static @Nullable ClientSession doGetSession(MongoDatabaseFactory dbFactory,
SessionSynchronization sessionSynchronization) {
MongoResourceHolder resourceHolder = (MongoResourceHolder) TransactionSynchronizationManager.getResource(dbFactory);
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoResourceHolder.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoResourceHolder.java
index a1e8344a9f..81c25d0998 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoResourceHolder.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoResourceHolder.java
@@ -15,7 +15,7 @@
*/
package org.springframework.data.mongodb;
-import org.springframework.lang.Nullable;
+import org.jspecify.annotations.Nullable;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.support.ResourceHolderSupport;
@@ -23,8 +23,7 @@
/**
* MongoDB specific {@link ResourceHolderSupport resource holder}, wrapping a {@link ClientSession}.
- * {@link MongoTransactionManager} binds instances of this class to the thread.
- *
+ * {@link MongoTransactionManager} binds instances of this class to the thread.
* Note: Intended for internal usage only.
*
* @author Christoph Strobl
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoTransactionException.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoTransactionException.java
index 4215479f62..3d7bec6780 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoTransactionException.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoTransactionException.java
@@ -15,7 +15,7 @@
*/
package org.springframework.data.mongodb;
-import org.springframework.lang.Nullable;
+import org.jspecify.annotations.Nullable;
/**
* A specific {@link ClientSessionException} related to issues with a transaction such as aborted or non existing
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoTransactionManager.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoTransactionManager.java
index eda657f5f1..1f97bb69e9 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoTransactionManager.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoTransactionManager.java
@@ -15,8 +15,8 @@
*/
package org.springframework.data.mongodb;
+import org.jspecify.annotations.Nullable;
import org.springframework.beans.factory.InitializingBean;
-import org.springframework.lang.Nullable;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionException;
import org.springframework.transaction.TransactionSystemException;
@@ -36,19 +36,15 @@
/**
* A {@link org.springframework.transaction.PlatformTransactionManager} implementation that manages
- * {@link ClientSession} based transactions for a single {@link MongoDatabaseFactory}.
- *
- * Binds a {@link ClientSession} from the specified {@link MongoDatabaseFactory} to the thread.
- *
+ * {@link ClientSession} based transactions for a single {@link MongoDatabaseFactory}.
+ * Binds a {@link ClientSession} from the specified {@link MongoDatabaseFactory} to the thread.
* {@link TransactionDefinition#isReadOnly() Readonly} transactions operate on a {@link ClientSession} and enable causal
* consistency, and also {@link ClientSession#startTransaction() start}, {@link ClientSession#commitTransaction()
- * commit} or {@link ClientSession#abortTransaction() abort} a transaction.
- *
+ * commit} or {@link ClientSession#abortTransaction() abort} a transaction.
* Application code is required to retrieve the {@link com.mongodb.client.MongoDatabase} via
* {@link MongoDatabaseUtils#getDatabase(MongoDatabaseFactory)} instead of a standard
* {@link MongoDatabaseFactory#getMongoDatabase()} call. Spring classes such as
- * {@link org.springframework.data.mongodb.core.MongoTemplate} use this strategy implicitly.
- *
+ * {@link org.springframework.data.mongodb.core.MongoTemplate} use this strategy implicitly.
* By default failure of a {@literal commit} operation raises a {@link TransactionSystemException}. One may override
* {@link #doCommit(MongoTransactionObject)} to implement the
* Retry Commit Operation
@@ -80,7 +76,9 @@ public class MongoTransactionManager extends AbstractPlatformTransactionManager
* @see #setTransactionSynchronization(int)
*/
public MongoTransactionManager() {
+
this.transactionOptionsResolver = MongoTransactionOptionsResolver.defaultResolver();
+ this.options = MongoTransactionOptions.NONE;
}
/**
@@ -151,7 +149,8 @@ protected void doBegin(Object transaction, TransactionDefinition definition) thr
}
try {
- MongoTransactionOptions mongoTransactionOptions = transactionOptionsResolver.resolve(definition).mergeWith(options);
+ MongoTransactionOptions mongoTransactionOptions = transactionOptionsResolver.resolve(definition)
+ .mergeWith(options);
mongoTransactionObject.startTransaction(mongoTransactionOptions.toDriverOptions());
} catch (MongoException ex) {
throw new TransactionSystemException(String.format("Could not start Mongo transaction for session %s.",
@@ -206,6 +205,7 @@ protected final void doCommit(DefaultTransactionStatus status) throws Transactio
* By default those labels are ignored, nevertheless one might check for
* {@link MongoException#UNKNOWN_TRANSACTION_COMMIT_RESULT_LABEL transient commit errors labels} and retry the the
* commit.
+ *
*
*
* int retries = 3;
@@ -302,8 +302,7 @@ public void setOptions(@Nullable TransactionOptions options) {
*
* @return can be {@literal null}.
*/
- @Nullable
- public MongoDatabaseFactory getDatabaseFactory() {
+ public @Nullable MongoDatabaseFactory getDatabaseFactory() {
return databaseFactory;
}
@@ -461,8 +460,7 @@ void closeSession() {
}
}
- @Nullable
- public ClientSession getSession() {
+ public @Nullable ClientSession getSession() {
return resourceHolder != null ? resourceHolder.getSession() : null;
}
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoTransactionOptions.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoTransactionOptions.java
index e411bd5d2d..04bcd36e35 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoTransactionOptions.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoTransactionOptions.java
@@ -19,15 +19,16 @@
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
+import org.jspecify.annotations.Nullable;
import org.springframework.data.mongodb.core.ReadConcernAware;
import org.springframework.data.mongodb.core.ReadPreferenceAware;
import org.springframework.data.mongodb.core.WriteConcernAware;
-import org.springframework.lang.Nullable;
import com.mongodb.ReadConcern;
import com.mongodb.ReadPreference;
import com.mongodb.TransactionOptions;
import com.mongodb.WriteConcern;
+import org.springframework.lang.Contract;
/**
* Options to be applied within a specific transaction scope.
@@ -43,27 +44,23 @@ public interface MongoTransactionOptions
*/
MongoTransactionOptions NONE = new MongoTransactionOptions() {
- @Nullable
@Override
- public Duration getMaxCommitTime() {
+ public @Nullable Duration getMaxCommitTime() {
return null;
}
- @Nullable
@Override
- public ReadConcern getReadConcern() {
+ public @Nullable ReadConcern getReadConcern() {
return null;
}
- @Nullable
@Override
- public ReadPreference getReadPreference() {
+ public @Nullable ReadPreference getReadPreference() {
return null;
}
- @Nullable
@Override
- public WriteConcern getWriteConcern() {
+ public @Nullable WriteConcern getWriteConcern() {
return null;
}
};
@@ -76,6 +73,7 @@ public WriteConcern getWriteConcern() {
* @return new instance of {@link MongoTransactionOptions} or this if {@literal fallbackOptions} is {@literal null} or
* {@link #NONE}.
*/
+ @Contract("null -> this")
default MongoTransactionOptions mergeWith(@Nullable MongoTransactionOptions fallbackOptions) {
if (fallbackOptions == null || MongoTransactionOptions.NONE.equals(fallbackOptions)) {
@@ -84,30 +82,26 @@ default MongoTransactionOptions mergeWith(@Nullable MongoTransactionOptions fall
return new MongoTransactionOptions() {
- @Nullable
@Override
- public Duration getMaxCommitTime() {
+ public @Nullable Duration getMaxCommitTime() {
return MongoTransactionOptions.this.hasMaxCommitTime() ? MongoTransactionOptions.this.getMaxCommitTime()
: fallbackOptions.getMaxCommitTime();
}
- @Nullable
@Override
- public ReadConcern getReadConcern() {
+ public @Nullable ReadConcern getReadConcern() {
return MongoTransactionOptions.this.hasReadConcern() ? MongoTransactionOptions.this.getReadConcern()
: fallbackOptions.getReadConcern();
}
- @Nullable
@Override
- public ReadPreference getReadPreference() {
+ public @Nullable ReadPreference getReadPreference() {
return MongoTransactionOptions.this.hasReadPreference() ? MongoTransactionOptions.this.getReadPreference()
: fallbackOptions.getReadPreference();
}
- @Nullable
@Override
- public WriteConcern getWriteConcern() {
+ public @Nullable WriteConcern getWriteConcern() {
return MongoTransactionOptions.this.hasWriteConcern() ? MongoTransactionOptions.this.getWriteConcern()
: fallbackOptions.getWriteConcern();
}
@@ -128,8 +122,8 @@ default T map(Function mappingFunction) {
* @return MongoDB driver native {@link TransactionOptions}.
* @see MongoTransactionOptions#map(Function)
*/
- @Nullable
- default TransactionOptions toDriverOptions() {
+ @SuppressWarnings("NullAway")
+ default @Nullable TransactionOptions toDriverOptions() {
return map(it -> {
@@ -157,7 +151,7 @@ default TransactionOptions toDriverOptions() {
/**
* Factory method to wrap given MongoDB driver native {@link TransactionOptions} into {@link MongoTransactionOptions}.
*
- * @param options
+ * @param options can be {@literal null}.
* @return {@link MongoTransactionOptions#NONE} if given object is {@literal null}.
*/
static MongoTransactionOptions of(@Nullable TransactionOptions options) {
@@ -168,35 +162,30 @@ static MongoTransactionOptions of(@Nullable TransactionOptions options) {
return new MongoTransactionOptions() {
- @Nullable
@Override
- public Duration getMaxCommitTime() {
+ public @Nullable Duration getMaxCommitTime() {
Long millis = options.getMaxCommitTime(TimeUnit.MILLISECONDS);
return millis != null ? Duration.ofMillis(millis) : null;
}
- @Nullable
@Override
- public ReadConcern getReadConcern() {
+ public @Nullable ReadConcern getReadConcern() {
return options.getReadConcern();
}
- @Nullable
@Override
- public ReadPreference getReadPreference() {
+ public @Nullable ReadPreference getReadPreference() {
return options.getReadPreference();
}
- @Nullable
@Override
- public WriteConcern getWriteConcern() {
+ public @Nullable WriteConcern getWriteConcern() {
return options.getWriteConcern();
}
- @Nullable
@Override
- public TransactionOptions toDriverOptions() {
+ public @Nullable TransactionOptions toDriverOptions() {
return options;
}
};
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoTransactionOptionsResolver.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoTransactionOptionsResolver.java
index b73b079a99..c4bdbcca53 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoTransactionOptionsResolver.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoTransactionOptionsResolver.java
@@ -18,7 +18,7 @@
import java.util.Map;
import java.util.stream.Collectors;
-import org.springframework.lang.Nullable;
+import org.jspecify.annotations.Nullable;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.interceptor.TransactionAttribute;
import org.springframework.util.Assert;
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/ReactiveMongoDatabaseUtils.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/ReactiveMongoDatabaseUtils.java
index f397818a4c..3d1c2ee89c 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/ReactiveMongoDatabaseUtils.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/ReactiveMongoDatabaseUtils.java
@@ -18,7 +18,7 @@
import reactor.core.publisher.Mono;
import reactor.util.context.Context;
-import org.springframework.lang.Nullable;
+import org.jspecify.annotations.Nullable;
import org.springframework.transaction.NoTransactionException;
import org.springframework.transaction.reactive.ReactiveResourceSynchronization;
import org.springframework.transaction.reactive.TransactionSynchronization;
@@ -35,8 +35,7 @@
/**
* Helper class for managing reactive {@link MongoDatabase} instances via {@link ReactiveMongoDatabaseFactory}. Used for
* obtaining {@link ClientSession session bound} resources, such as {@link MongoDatabase} and {@link MongoCollection}
- * suitable for transactional usage.
- *
+ * suitable for transactional usage.
* Note: Intended for internal usage only.
*
* @author Mark Paluch
@@ -74,8 +73,7 @@ public static Mono isTransactionActive(ReactiveMongoDatabaseFactory dat
/**
* Obtain the default {@link MongoDatabase database} form the given {@link ReactiveMongoDatabaseFactory factory} using
- * {@link SessionSynchronization#ON_ACTUAL_TRANSACTION native session synchronization}.
- *
+ * {@link SessionSynchronization#ON_ACTUAL_TRANSACTION native session synchronization}.
* Registers a {@link MongoSessionSynchronization MongoDB specific transaction synchronization} within the subscriber
* {@link Context} if {@link TransactionSynchronizationManager#isSynchronizationActive() synchronization is active}.
*
@@ -103,32 +101,32 @@ public static Mono getDatabase(ReactiveMongoDatabaseFactory facto
/**
* Obtain the {@link MongoDatabase database} with given name form the given {@link ReactiveMongoDatabaseFactory
- * factory} using {@link SessionSynchronization#ON_ACTUAL_TRANSACTION native session synchronization}.
- *
+ * factory} using {@link SessionSynchronization#ON_ACTUAL_TRANSACTION native session synchronization}.
* Registers a {@link MongoSessionSynchronization MongoDB specific transaction synchronization} within the subscriber
* {@link Context} if {@link TransactionSynchronizationManager#isSynchronizationActive() synchronization is active}.
*
- * @param dbName the name of the {@link MongoDatabase} to get.
+ * @param dbName the name of the {@link MongoDatabase} to get. If {@literal null} the default database of the
+ * {@link ReactiveMongoDatabaseFactory}.
* @param factory the {@link ReactiveMongoDatabaseFactory} to get the {@link MongoDatabase} from.
* @return the {@link MongoDatabase} that is potentially associated with a transactional {@link ClientSession}.
*/
- public static Mono getDatabase(String dbName, ReactiveMongoDatabaseFactory factory) {
+ public static Mono getDatabase(@Nullable String dbName, ReactiveMongoDatabaseFactory factory) {
return doGetMongoDatabase(dbName, factory, SessionSynchronization.ON_ACTUAL_TRANSACTION);
}
/**
* Obtain the {@link MongoDatabase database} with given name form the given {@link ReactiveMongoDatabaseFactory
- * factory}.
- *
+ * factory}.
* Registers a {@link MongoSessionSynchronization MongoDB specific transaction synchronization} within the subscriber
* {@link Context} if {@link TransactionSynchronizationManager#isSynchronizationActive() synchronization is active}.
*
- * @param dbName the name of the {@link MongoDatabase} to get.
+ * @param dbName the name of the {@link MongoDatabase} to get. If {@literal null} the default database of the *
+ * {@link ReactiveMongoDatabaseFactory}.
* @param factory the {@link ReactiveMongoDatabaseFactory} to get the {@link MongoDatabase} from.
* @param sessionSynchronization the synchronization to use. Must not be {@literal null}.
* @return the {@link MongoDatabase} that is potentially associated with a transactional {@link ClientSession}.
*/
- public static Mono getDatabase(String dbName, ReactiveMongoDatabaseFactory factory,
+ public static Mono getDatabase(@Nullable String dbName, ReactiveMongoDatabaseFactory factory,
SessionSynchronization sessionSynchronization) {
return doGetMongoDatabase(dbName, factory, sessionSynchronization);
}
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/ReactiveMongoResourceHolder.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/ReactiveMongoResourceHolder.java
index 33caa5e7fe..d01364b202 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/ReactiveMongoResourceHolder.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/ReactiveMongoResourceHolder.java
@@ -15,16 +15,15 @@
*/
package org.springframework.data.mongodb;
+import org.jspecify.annotations.Nullable;
import org.springframework.data.mongodb.core.ReactiveMongoTemplate;
-import org.springframework.lang.Nullable;
import org.springframework.transaction.support.ResourceHolderSupport;
import com.mongodb.reactivestreams.client.ClientSession;
/**
* MongoDB specific resource holder, wrapping a {@link ClientSession}. {@link ReactiveMongoTransactionManager} binds
- * instances of this class to the subscriber context.
- *
+ * instances of this class to the subscriber context.
* Note: Intended for internal usage only.
*
* @author Mark Paluch
@@ -103,8 +102,7 @@ boolean hasSession() {
* @param session
* @return
*/
- @Nullable
- public ClientSession setSessionIfAbsent(@Nullable ClientSession session) {
+ public @Nullable ClientSession setSessionIfAbsent(@Nullable ClientSession session) {
if (!hasSession()) {
setSession(session);
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/ReactiveMongoTransactionManager.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/ReactiveMongoTransactionManager.java
index 2c65c26b79..4f293c8ed6 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/ReactiveMongoTransactionManager.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/ReactiveMongoTransactionManager.java
@@ -17,8 +17,8 @@
import reactor.core.publisher.Mono;
+import org.jspecify.annotations.Nullable;
import org.springframework.beans.factory.InitializingBean;
-import org.springframework.lang.Nullable;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionException;
import org.springframework.transaction.TransactionSystemException;
@@ -64,7 +64,7 @@
public class ReactiveMongoTransactionManager extends AbstractReactiveTransactionManager implements InitializingBean {
private @Nullable ReactiveMongoDatabaseFactory databaseFactory;
- private @Nullable MongoTransactionOptions options;
+ private MongoTransactionOptions options;
private final MongoTransactionOptionsResolver transactionOptionsResolver;
/**
@@ -79,7 +79,9 @@ public class ReactiveMongoTransactionManager extends AbstractReactiveTransaction
* @see #setDatabaseFactory(ReactiveMongoDatabaseFactory)
*/
public ReactiveMongoTransactionManager() {
+
this.transactionOptionsResolver = MongoTransactionOptionsResolver.defaultResolver();
+ this.options = MongoTransactionOptions.NONE;
}
/**
@@ -98,7 +100,7 @@ public ReactiveMongoTransactionManager(ReactiveMongoDatabaseFactory databaseFact
* starting a new transaction.
*
* @param databaseFactory must not be {@literal null}.
- * @param options can be {@literal null}.
+ * @param options can be {@literal null}. Will default {@link MongoTransactionOptions#NONE} if {@literal null}.
*/
public ReactiveMongoTransactionManager(ReactiveMongoDatabaseFactory databaseFactory,
@Nullable TransactionOptions options) {
@@ -112,7 +114,8 @@ public ReactiveMongoTransactionManager(ReactiveMongoDatabaseFactory databaseFact
*
* @param databaseFactory must not be {@literal null}.
* @param transactionOptionsResolver must not be {@literal null}.
- * @param defaultTransactionOptions can be {@literal null}.
+ * @param defaultTransactionOptions can be {@literal null}. Will default {@link MongoTransactionOptions#NONE} if
+ * {@literal null}.
* @since 4.3
*/
public ReactiveMongoTransactionManager(ReactiveMongoDatabaseFactory databaseFactory,
@@ -124,7 +127,7 @@ public ReactiveMongoTransactionManager(ReactiveMongoDatabaseFactory databaseFact
this.databaseFactory = databaseFactory;
this.transactionOptionsResolver = transactionOptionsResolver;
- this.options = defaultTransactionOptions;
+ this.options = defaultTransactionOptions != null ? defaultTransactionOptions : MongoTransactionOptions.NONE;
}
@Override
@@ -318,8 +321,7 @@ public void setOptions(@Nullable TransactionOptions options) {
*
* @return can be {@literal null}.
*/
- @Nullable
- public ReactiveMongoDatabaseFactory getDatabaseFactory() {
+ public @Nullable ReactiveMongoDatabaseFactory getDatabaseFactory() {
return databaseFactory;
}
@@ -470,8 +472,7 @@ void closeSession() {
}
}
- @Nullable
- public ClientSession getSession() {
+ public @Nullable ClientSession getSession() {
return resourceHolder != null ? resourceHolder.getSession() : null;
}
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/SessionAwareMethodInterceptor.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/SessionAwareMethodInterceptor.java
index 93dbf5db69..ec30478a54 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/SessionAwareMethodInterceptor.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/SessionAwareMethodInterceptor.java
@@ -22,8 +22,8 @@
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
+import org.jspecify.annotations.Nullable;
import org.springframework.core.MethodClassKey;
-import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ConcurrentReferenceHashMap;
@@ -34,8 +34,7 @@
/**
* {@link MethodInterceptor} implementation looking up and invoking an alternative target method having
- * {@link ClientSession} as its first argument. This allows seamless integration with the existing code base.
- *
+ * {@link ClientSession} as its first argument. This allows seamless integration with the existing code base.
* The {@link MethodInterceptor} is aware of methods on {@code MongoCollection} that my return new instances of itself
* like (eg. {@link com.mongodb.reactivestreams.client.MongoCollection#withWriteConcern(WriteConcern)} and decorate them
* if not already proxied.
@@ -95,13 +94,13 @@ public SessionAwareMethodInterceptor(ClientSession session, T target, Class<
this.sessionType = sessionType;
}
- @Nullable
@Override
- public Object invoke(MethodInvocation methodInvocation) throws Throwable {
+ public @Nullable Object invoke(MethodInvocation methodInvocation) throws Throwable {
if (requiresDecoration(methodInvocation.getMethod())) {
Object target = methodInvocation.proceed();
+ Assert.notNull(target, "invocation target was null");
if (target instanceof Proxy) {
return target;
}
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/SimpleMongoTransactionOptions.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/SimpleMongoTransactionOptions.java
index b52fc0bd71..5c50ba686a 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/SimpleMongoTransactionOptions.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/SimpleMongoTransactionOptions.java
@@ -21,7 +21,7 @@
import java.util.Set;
import java.util.stream.Collectors;
-import org.springframework.lang.Nullable;
+import org.jspecify.annotations.Nullable;
import org.springframework.util.Assert;
import com.mongodb.Function;
@@ -41,10 +41,10 @@ class SimpleMongoTransactionOptions implements MongoTransactionOptions {
static final Set KNOWN_KEYS = Arrays.stream(OptionKey.values()).map(OptionKey::getKey)
.collect(Collectors.toSet());
- private final Duration maxCommitTime;
- private final ReadConcern readConcern;
- private final ReadPreference readPreference;
- private final WriteConcern writeConcern;
+ private final @Nullable Duration maxCommitTime;
+ private final @Nullable ReadConcern readConcern;
+ private final @Nullable ReadPreference readPreference;
+ private final @Nullable WriteConcern writeConcern;
static SimpleMongoTransactionOptions of(Map options) {
return new SimpleMongoTransactionOptions(options);
@@ -58,27 +58,23 @@ private SimpleMongoTransactionOptions(Map options) {
this.writeConcern = doGetWriteConcern(options);
}
- @Nullable
@Override
- public Duration getMaxCommitTime() {
+ public @Nullable Duration getMaxCommitTime() {
return maxCommitTime;
}
- @Nullable
@Override
- public ReadConcern getReadConcern() {
+ public @Nullable ReadConcern getReadConcern() {
return readConcern;
}
- @Nullable
@Override
- public ReadPreference getReadPreference() {
+ public @Nullable ReadPreference getReadPreference() {
return readPreference;
}
- @Nullable
@Override
- public WriteConcern getWriteConcern() {
+ public @Nullable WriteConcern getWriteConcern() {
return writeConcern;
}
@@ -89,8 +85,7 @@ public String toString() {
+ ", readPreference=" + readPreference + ", writeConcern=" + writeConcern + '}';
}
- @Nullable
- private static Duration doGetMaxCommitTime(Map options) {
+ private static @Nullable Duration doGetMaxCommitTime(Map options) {
return getValue(options, OptionKey.MAX_COMMIT_TIME, value -> {
@@ -100,18 +95,15 @@ private static Duration doGetMaxCommitTime(Map options) {
});
}
- @Nullable
- private static ReadConcern doGetReadConcern(Map options) {
+ private static @Nullable ReadConcern doGetReadConcern(Map options) {
return getValue(options, OptionKey.READ_CONCERN, value -> new ReadConcern(ReadConcernLevel.fromString(value)));
}
- @Nullable
- private static ReadPreference doGetReadPreference(Map options) {
+ private static @Nullable ReadPreference doGetReadPreference(Map options) {
return getValue(options, OptionKey.READ_PREFERENCE, ReadPreference::valueOf);
}
- @Nullable
- private static WriteConcern doGetWriteConcern(Map options) {
+ private static @Nullable WriteConcern doGetWriteConcern(Map options) {
return getValue(options, OptionKey.WRITE_CONCERN, value -> {
@@ -123,8 +115,8 @@ private static WriteConcern doGetWriteConcern(Map options) {
});
}
- @Nullable
- private static T getValue(Map options, OptionKey key, Function convertFunction) {
+ private static @Nullable T getValue(Map options, OptionKey key,
+ Function convertFunction) {
String value = options.get(key.getKey());
return value != null ? convertFunction.apply(value) : null;
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/TransactionMetadata.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/TransactionMetadata.java
index cd5f58d5b1..57ecec0342 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/TransactionMetadata.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/TransactionMetadata.java
@@ -17,7 +17,7 @@
import java.time.Duration;
-import org.springframework.lang.Nullable;
+import org.jspecify.annotations.Nullable;
/**
* MongoDB-specific transaction metadata.
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/TransactionOptionResolver.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/TransactionOptionResolver.java
index 37c7e3686b..e42c26d95a 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/TransactionOptionResolver.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/TransactionOptionResolver.java
@@ -15,7 +15,7 @@
*/
package org.springframework.data.mongodb;
-import org.springframework.lang.Nullable;
+import org.jspecify.annotations.Nullable;
import org.springframework.transaction.TransactionDefinition;
/**
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/UncategorizedMongoDbException.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/UncategorizedMongoDbException.java
index bec05d0d68..69ec086e5a 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/UncategorizedMongoDbException.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/UncategorizedMongoDbException.java
@@ -15,8 +15,8 @@
*/
package org.springframework.data.mongodb;
+import org.jspecify.annotations.Nullable;
import org.springframework.dao.UncategorizedDataAccessException;
-import org.springframework.lang.Nullable;
public class UncategorizedMongoDbException extends UncategorizedDataAccessException {
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/aot/MongoAotPredicates.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/aot/MongoAotPredicates.java
index 2fe27a2c9e..86a70600a8 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/aot/MongoAotPredicates.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/aot/MongoAotPredicates.java
@@ -17,11 +17,11 @@
import java.util.function.Predicate;
+import org.jspecify.annotations.Nullable;
import org.springframework.data.mongodb.core.mapping.MongoSimpleTypes;
import org.springframework.data.util.ReactiveWrappers;
import org.springframework.data.util.ReactiveWrappers.ReactiveLibrary;
import org.springframework.data.util.TypeUtils;
-import org.springframework.lang.Nullable;
import org.springframework.util.ClassUtils;
/**
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/aot/MongoManagedTypesBeanRegistrationAotProcessor.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/aot/MongoManagedTypesBeanRegistrationAotProcessor.java
index a33f20ffb6..4b7aa10c3f 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/aot/MongoManagedTypesBeanRegistrationAotProcessor.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/aot/MongoManagedTypesBeanRegistrationAotProcessor.java
@@ -15,11 +15,11 @@
*/
package org.springframework.data.mongodb.aot;
+import org.jspecify.annotations.Nullable;
import org.springframework.aot.generate.GenerationContext;
import org.springframework.core.ResolvableType;
import org.springframework.data.aot.ManagedTypesBeanRegistrationAotProcessor;
import org.springframework.data.mongodb.MongoManagedTypes;
-import org.springframework.lang.Nullable;
import org.springframework.util.ClassUtils;
/**
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/aot/MongoRuntimeHints.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/aot/MongoRuntimeHints.java
index 538fe4e812..f2442960ed 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/aot/MongoRuntimeHints.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/aot/MongoRuntimeHints.java
@@ -15,10 +15,11 @@
*/
package org.springframework.data.mongodb.aot;
-import static org.springframework.data.mongodb.aot.MongoAotPredicates.*;
+import static org.springframework.data.mongodb.aot.MongoAotPredicates.isReactorPresent;
import java.util.Arrays;
+import org.jspecify.annotations.Nullable;
import org.springframework.aot.hint.MemberCategory;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.RuntimeHintsRegistrar;
@@ -31,7 +32,6 @@
import org.springframework.data.mongodb.core.mapping.event.ReactiveAfterSaveCallback;
import org.springframework.data.mongodb.core.mapping.event.ReactiveBeforeConvertCallback;
import org.springframework.data.mongodb.core.mapping.event.ReactiveBeforeSaveCallback;
-import org.springframework.lang.Nullable;
import org.springframework.util.ClassUtils;
import com.mongodb.MongoClientSettings;
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/ConnectionStringPropertyEditor.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/ConnectionStringPropertyEditor.java
index b070a0190f..0f6ba01704 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/ConnectionStringPropertyEditor.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/ConnectionStringPropertyEditor.java
@@ -17,7 +17,7 @@
import java.beans.PropertyEditorSupport;
-import org.springframework.lang.Nullable;
+import org.jspecify.annotations.Nullable;
import org.springframework.util.StringUtils;
import com.mongodb.ConnectionString;
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MappingMongoConverterParser.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MappingMongoConverterParser.java
index 164b4defb6..f3a7dc0437 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MappingMongoConverterParser.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MappingMongoConverterParser.java
@@ -21,6 +21,8 @@
import java.util.List;
import java.util.Set;
+import org.jspecify.annotations.NullUnmarked;
+import org.jspecify.annotations.Nullable;
import org.springframework.beans.BeanMetadataElement;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
@@ -56,7 +58,6 @@
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
import org.springframework.data.mongodb.core.mapping.event.ValidatingMongoEventListener;
-import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;
@@ -76,6 +77,7 @@
* @author Zied Yaich
* @author Tomasz Forys
*/
+@NullUnmarked
public class MappingMongoConverterParser implements BeanDefinitionParser {
private static final String BASE_PACKAGE = "base-package";
@@ -157,8 +159,7 @@ public BeanDefinition parse(Element element, ParserContext parserContext) {
return null;
}
- @Nullable
- private BeanDefinition potentiallyCreateValidatingMongoEventListener(Element element, ParserContext parserContext) {
+ private @Nullable BeanDefinition potentiallyCreateValidatingMongoEventListener(Element element, ParserContext parserContext) {
String disableValidation = element.getAttribute("disable-validation");
boolean validationDisabled = StringUtils.hasText(disableValidation) && Boolean.parseBoolean(disableValidation);
@@ -291,8 +292,7 @@ private static void parseFieldNamingStrategy(Element element, ReaderContext cont
}
}
- @Nullable
- private BeanDefinition getCustomConversions(Element element, ParserContext parserContext) {
+ private @Nullable BeanDefinition getCustomConversions(Element element, ParserContext parserContext) {
List customConvertersElements = DomUtils.getChildElementsByTagName(element, "custom-converters");
@@ -354,8 +354,7 @@ private static Set getInitialEntityClasses(Element element) {
return classes;
}
- @Nullable
- public BeanMetadataElement parseConverter(Element element, ParserContext parserContext) {
+ public @Nullable BeanMetadataElement parseConverter(Element element, ParserContext parserContext) {
String converterRef = element.getAttribute("ref");
if (StringUtils.hasText(converterRef)) {
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoAuditingBeanDefinitionParser.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoAuditingBeanDefinitionParser.java
index 4e05fe6c39..a304199776 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoAuditingBeanDefinitionParser.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoAuditingBeanDefinitionParser.java
@@ -18,6 +18,8 @@
import static org.springframework.data.config.ParsingUtils.*;
import static org.springframework.data.mongodb.config.BeanNames.*;
+import org.jspecify.annotations.NullUnmarked;
+import org.jspecify.annotations.Nullable;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
@@ -29,7 +31,6 @@
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
import org.springframework.data.mongodb.core.mapping.event.AuditingEntityCallback;
import org.springframework.data.mongodb.core.mapping.event.ReactiveAuditingEntityCallback;
-import org.springframework.lang.Nullable;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
@@ -42,6 +43,7 @@
* @author Oliver Gierke
* @author Mark Paluch
*/
+@NullUnmarked
public class MongoAuditingBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {
private static boolean PROJECT_REACTOR_AVAILABLE = ClassUtils.isPresent("reactor.core.publisher.Mono",
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoConfigurationSupport.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoConfigurationSupport.java
index 0594f6176c..b01827d8c6 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoConfigurationSupport.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoConfigurationSupport.java
@@ -35,6 +35,7 @@
import org.springframework.data.mongodb.core.convert.MongoCustomConversions.MongoConverterConfigurationAdapter;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
+import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
@@ -52,7 +53,7 @@ public abstract class MongoConfigurationSupport {
/**
* Return the name of the database to connect to.
*
- * @return must not be {@literal null}.
+ * @return never {@literal null}.
*/
protected abstract String getDatabaseName();
@@ -76,7 +77,7 @@ protected Collection getMappingBasePackages() {
* Creates a {@link MongoMappingContext} equipped with entity classes scanned from the mapping base package.
*
* @see #getMappingBasePackages()
- * @return
+ * @return never {@literal null}.
*/
@Bean
public MongoMappingContext mongoMappingContext(MongoCustomConversions customConversions,
@@ -172,8 +173,10 @@ protected Set> scanForEntities(String basePackage) throws ClassNotFound
for (BeanDefinition candidate : componentProvider.findCandidateComponents(basePackage)) {
- initialEntitySet
- .add(ClassUtils.forName(candidate.getBeanClassName(), MongoConfigurationSupport.class.getClassLoader()));
+ String beanClassName = candidate.getBeanClassName();
+ Assert.notNull(beanClassName, "BeanClassName cannot be null");
+
+ initialEntitySet.add(ClassUtils.forName(beanClassName, MongoConfigurationSupport.class.getClassLoader()));
}
}
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoCredentialPropertyEditor.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoCredentialPropertyEditor.java
index b8f23a35af..93d778c861 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoCredentialPropertyEditor.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoCredentialPropertyEditor.java
@@ -26,7 +26,7 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import org.springframework.lang.Nullable;
+import org.jspecify.annotations.Nullable;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils;
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoDbFactoryParser.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoDbFactoryParser.java
index 2e733cc79f..2d3649c53a 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoDbFactoryParser.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoDbFactoryParser.java
@@ -20,6 +20,8 @@
import java.util.Set;
+import org.jspecify.annotations.NullUnmarked;
+import org.jspecify.annotations.Nullable;
import org.springframework.beans.factory.BeanDefinitionStoreException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.parsing.BeanComponentDefinition;
@@ -31,7 +33,6 @@
import org.springframework.data.config.BeanComponentDefinitionBuilder;
import org.springframework.data.mongodb.core.MongoClientFactoryBean;
import org.springframework.data.mongodb.core.SimpleMongoClientDatabaseFactory;
-import org.springframework.lang.Nullable;
import org.springframework.util.StringUtils;
import org.w3c.dom.Element;
@@ -47,6 +48,7 @@
* @author Viktor Khoroshko
* @author Mark Paluch
*/
+@NullUnmarked
public class MongoDbFactoryParser extends AbstractBeanDefinitionParser {
private static final Set MONGO_URI_ALLOWED_ADDITIONAL_ATTRIBUTES = Set.of("id", "write-concern");
@@ -125,8 +127,7 @@ private BeanDefinition registerMongoBeanDefinition(Element element, ParserContex
* @param parserContext
* @return {@literal null} in case no client-/uri defined.
*/
- @Nullable
- private BeanDefinition getConnectionString(Element element, ParserContext parserContext) {
+ private @Nullable BeanDefinition getConnectionString(Element element, ParserContext parserContext) {
String type = null;
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoJmxParser.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoJmxParser.java
deleted file mode 100644
index 07e9aace0c..0000000000
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoJmxParser.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright 2011-2025 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.springframework.data.mongodb.config;
-
-import org.springframework.beans.factory.config.BeanDefinition;
-import org.springframework.beans.factory.parsing.BeanComponentDefinition;
-import org.springframework.beans.factory.parsing.CompositeComponentDefinition;
-import org.springframework.beans.factory.support.BeanDefinitionBuilder;
-import org.springframework.beans.factory.xml.BeanDefinitionParser;
-import org.springframework.beans.factory.xml.ParserContext;
-import org.springframework.data.mongodb.core.MongoAdmin;
-import org.springframework.data.mongodb.monitor.*;
-import org.springframework.util.StringUtils;
-import org.w3c.dom.Element;
-
-/**
- * @author Mark Pollack
- * @author Thomas Risberg
- * @author John Brisbin
- * @author Oliver Gierke
- * @author Christoph Strobl
- */
-public class MongoJmxParser implements BeanDefinitionParser {
-
- public BeanDefinition parse(Element element, ParserContext parserContext) {
- String name = element.getAttribute("mongo-ref");
- if (!StringUtils.hasText(name)) {
- name = BeanNames.MONGO_BEAN_NAME;
- }
- registerJmxComponents(name, element, parserContext);
- return null;
- }
-
- protected void registerJmxComponents(String mongoRefName, Element element, ParserContext parserContext) {
- Object eleSource = parserContext.extractSource(element);
-
- CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), eleSource);
-
- createBeanDefEntry(AssertMetrics.class, compositeDef, mongoRefName, eleSource, parserContext);
- createBeanDefEntry(BackgroundFlushingMetrics.class, compositeDef, mongoRefName, eleSource, parserContext);
- createBeanDefEntry(BtreeIndexCounters.class, compositeDef, mongoRefName, eleSource, parserContext);
- createBeanDefEntry(ConnectionMetrics.class, compositeDef, mongoRefName, eleSource, parserContext);
- createBeanDefEntry(GlobalLockMetrics.class, compositeDef, mongoRefName, eleSource, parserContext);
- createBeanDefEntry(MemoryMetrics.class, compositeDef, mongoRefName, eleSource, parserContext);
- createBeanDefEntry(OperationCounters.class, compositeDef, mongoRefName, eleSource, parserContext);
- createBeanDefEntry(ServerInfo.class, compositeDef, mongoRefName, eleSource, parserContext);
- createBeanDefEntry(MongoAdmin.class, compositeDef, mongoRefName, eleSource, parserContext);
-
- parserContext.registerComponent(compositeDef);
-
- }
-
- protected void createBeanDefEntry(Class> clazz, CompositeComponentDefinition compositeDef, String mongoRefName,
- Object eleSource, ParserContext parserContext) {
- BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(clazz);
- builder.getRawBeanDefinition().setSource(eleSource);
- builder.addConstructorArgReference(mongoRefName);
- BeanDefinition assertDef = builder.getBeanDefinition();
- String assertName = parserContext.getReaderContext().registerWithGeneratedName(assertDef);
- compositeDef.addNestedComponent(new BeanComponentDefinition(assertDef, assertName));
- }
-
-}
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoNamespaceHandler.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoNamespaceHandler.java
index 47519ca615..62a4a1082d 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoNamespaceHandler.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoNamespaceHandler.java
@@ -31,7 +31,6 @@ public void init() {
registerBeanDefinitionParser("mapping-converter", new MappingMongoConverterParser());
registerBeanDefinitionParser("mongo-client", new MongoClientParser());
registerBeanDefinitionParser("db-factory", new MongoDbFactoryParser());
- registerBeanDefinitionParser("jmx", new MongoJmxParser());
registerBeanDefinitionParser("auditing", new MongoAuditingBeanDefinitionParser());
registerBeanDefinitionParser("template", new MongoTemplateParser());
registerBeanDefinitionParser("gridFsTemplate", new GridFsTemplateParser());
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoParsingUtils.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoParsingUtils.java
index 95b56b58f3..00e993fdc8 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoParsingUtils.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoParsingUtils.java
@@ -19,6 +19,7 @@
import java.util.Map;
+import org.jspecify.annotations.NullUnmarked;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.CustomEditorConfigurer;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
@@ -40,6 +41,7 @@
* @author Christoph Strobl
* @author Mark Paluch
*/
+@NullUnmarked
abstract class MongoParsingUtils {
private MongoParsingUtils() {}
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoTemplateParser.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoTemplateParser.java
index 1e1b11356f..5053e540fe 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoTemplateParser.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoTemplateParser.java
@@ -18,6 +18,7 @@
import static org.springframework.data.config.ParsingUtils.*;
import static org.springframework.data.mongodb.config.MongoParsingUtils.*;
+import org.jspecify.annotations.NullUnmarked;
import org.springframework.beans.factory.BeanDefinitionStoreException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.parsing.BeanComponentDefinition;
@@ -37,6 +38,7 @@
* @author Martin Baumgartner
* @author Oliver Gierke
*/
+@NullUnmarked
class MongoTemplateParser extends AbstractBeanDefinitionParser {
@Override
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/ReadConcernPropertyEditor.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/ReadConcernPropertyEditor.java
index 60bf126ae7..3f5cb0ca62 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/ReadConcernPropertyEditor.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/ReadConcernPropertyEditor.java
@@ -17,7 +17,7 @@
import java.beans.PropertyEditorSupport;
-import org.springframework.lang.Nullable;
+import org.jspecify.annotations.Nullable;
import org.springframework.util.StringUtils;
import com.mongodb.ReadConcern;
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/ReadPreferencePropertyEditor.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/ReadPreferencePropertyEditor.java
index 5ed9b66619..f24c435348 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/ReadPreferencePropertyEditor.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/ReadPreferencePropertyEditor.java
@@ -17,10 +17,10 @@
import java.beans.PropertyEditorSupport;
-import org.springframework.lang.Nullable;
-
import com.mongodb.ReadPreference;
+import org.jspecify.annotations.Nullable;
+
/**
* Parse a {@link String} to a {@link ReadPreference}.
*
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/ServerAddressPropertyEditor.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/ServerAddressPropertyEditor.java
index 9c51900902..9ff59e5b22 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/ServerAddressPropertyEditor.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/ServerAddressPropertyEditor.java
@@ -23,7 +23,7 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.springframework.lang.Nullable;
+import org.jspecify.annotations.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
@@ -80,11 +80,10 @@ public void setAsText(@Nullable String replicaSetString) {
* @param source
* @return the
*/
- @Nullable
- private ServerAddress parseServerAddress(String source) {
+ private @Nullable ServerAddress parseServerAddress(String source) {
if (!StringUtils.hasText(source)) {
- if(LOG.isWarnEnabled()) {
+ if (LOG.isWarnEnabled()) {
LOG.warn(String.format(COULD_NOT_PARSE_ADDRESS_MESSAGE, "source", source));
}
return null;
@@ -93,7 +92,7 @@ private ServerAddress parseServerAddress(String source) {
String[] hostAndPort = extractHostAddressAndPort(source.trim());
if (hostAndPort.length > 2) {
- if(LOG.isWarnEnabled()) {
+ if (LOG.isWarnEnabled()) {
LOG.warn(String.format(COULD_NOT_PARSE_ADDRESS_MESSAGE, "source", source));
}
return null;
@@ -105,11 +104,11 @@ private ServerAddress parseServerAddress(String source) {
return port == null ? new ServerAddress(hostAddress) : new ServerAddress(hostAddress, port);
} catch (UnknownHostException e) {
- if(LOG.isWarnEnabled()) {
+ if (LOG.isWarnEnabled()) {
LOG.warn(String.format(COULD_NOT_PARSE_ADDRESS_MESSAGE, "host", hostAndPort[0]));
}
} catch (NumberFormatException e) {
- if(LOG.isWarnEnabled()) {
+ if (LOG.isWarnEnabled()) {
LOG.warn(String.format(COULD_NOT_PARSE_ADDRESS_MESSAGE, "port", hostAndPort[1]));
}
}
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/UUidRepresentationPropertyEditor.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/UUidRepresentationPropertyEditor.java
index b777969967..23c15102ac 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/UUidRepresentationPropertyEditor.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/UUidRepresentationPropertyEditor.java
@@ -18,7 +18,7 @@
import java.beans.PropertyEditorSupport;
import org.bson.UuidRepresentation;
-import org.springframework.lang.Nullable;
+import org.jspecify.annotations.Nullable;
import org.springframework.util.StringUtils;
/**
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/WriteConcernPropertyEditor.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/WriteConcernPropertyEditor.java
index ee0d09e555..32c19e24c3 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/WriteConcernPropertyEditor.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/WriteConcernPropertyEditor.java
@@ -17,7 +17,7 @@
import java.beans.PropertyEditorSupport;
-import org.springframework.lang.Nullable;
+import org.jspecify.annotations.Nullable;
import org.springframework.util.StringUtils;
import com.mongodb.WriteConcern;
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/package-info.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/package-info.java
index 5a1e5b725e..555cc9f66e 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/package-info.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/package-info.java
@@ -1,6 +1,6 @@
/**
* Spring XML namespace configuration for MongoDB specific repositories.
*/
-@org.springframework.lang.NonNullApi
+@org.jspecify.annotations.NullMarked
package org.springframework.data.mongodb.config;
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/AggregationUtil.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/AggregationUtil.java
index a00d95a9ad..ec7c368eaf 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/AggregationUtil.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/AggregationUtil.java
@@ -18,7 +18,7 @@
import java.util.List;
import org.bson.Document;
-
+import org.jspecify.annotations.Nullable;
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationOperationContext;
@@ -30,7 +30,6 @@
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
import org.springframework.data.util.Lazy;
-import org.springframework.lang.Nullable;
/**
* Utility methods to map {@link org.springframework.data.mongodb.core.aggregation.Aggregation} pipeline definitions and
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ChangeStreamEvent.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ChangeStreamEvent.java
index 17b8835b7e..8a74ace28b 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ChangeStreamEvent.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ChangeStreamEvent.java
@@ -21,9 +21,9 @@
import org.bson.BsonTimestamp;
import org.bson.BsonValue;
import org.bson.Document;
+import org.jspecify.annotations.Nullable;
import org.springframework.data.mongodb.core.convert.MongoConverter;
import org.springframework.data.mongodb.core.messaging.Message;
-import org.springframework.lang.Nullable;
import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;
@@ -78,8 +78,7 @@ public ChangeStreamEvent(@Nullable ChangeStreamDocument raw, Class
*
* @return can be {@literal null}.
*/
- @Nullable
- public ChangeStreamDocument getRaw() {
+ public @Nullable ChangeStreamDocument getRaw() {
return raw;
}
@@ -88,10 +87,10 @@ public ChangeStreamDocument getRaw() {
*
* @return can be {@literal null}.
*/
- @Nullable
- public Instant getTimestamp() {
+ public @Nullable Instant getTimestamp() {
- return getBsonTimestamp() != null ? converter.getConversionService().convert(raw.getClusterTime(), Instant.class)
+ return getBsonTimestamp() != null && raw != null
+ ? converter.getConversionService().convert(raw.getClusterTime(), Instant.class)
: null;
}
@@ -111,8 +110,7 @@ public BsonTimestamp getBsonTimestamp() {
*
* @return can be {@literal null}.
*/
- @Nullable
- public BsonValue getResumeToken() {
+ public @Nullable BsonValue getResumeToken() {
return raw != null ? raw.getResumeToken() : null;
}
@@ -121,8 +119,7 @@ public BsonValue getResumeToken() {
*
* @return can be {@literal null}.
*/
- @Nullable
- public OperationType getOperationType() {
+ public @Nullable OperationType getOperationType() {
return raw != null ? raw.getOperationType() : null;
}
@@ -131,8 +128,7 @@ public OperationType getOperationType() {
*
* @return can be {@literal null}.
*/
- @Nullable
- public String getDatabaseName() {
+ public @Nullable String getDatabaseName() {
return raw != null ? raw.getNamespace().getDatabaseName() : null;
}
@@ -141,8 +137,7 @@ public String getDatabaseName() {
*
* @return can be {@literal null}.
*/
- @Nullable
- public String getCollectionName() {
+ public @Nullable String getCollectionName() {
return raw != null ? raw.getNamespace().getCollectionName() : null;
}
@@ -152,8 +147,7 @@ public String getCollectionName() {
* @return {@literal null} when {@link #getRaw()} or {@link ChangeStreamDocument#getFullDocument()} is
* {@literal null}.
*/
- @Nullable
- public T getBody() {
+ public @Nullable T getBody() {
if (raw == null || raw.getFullDocument() == null) {
return null;
@@ -163,14 +157,14 @@ public T getBody() {
}
/**
- * Get the potentially converted {@link ChangeStreamDocument#getFullDocumentBeforeChange() document} before being changed.
+ * Get the potentially converted {@link ChangeStreamDocument#getFullDocumentBeforeChange() document} before being
+ * changed.
*
* @return {@literal null} when {@link #getRaw()} or {@link ChangeStreamDocument#getFullDocumentBeforeChange()} is
* {@literal null}.
* @since 4.0
*/
- @Nullable
- public T getBodyBeforeChange() {
+ public @Nullable T getBodyBeforeChange() {
if (raw == null || raw.getFullDocumentBeforeChange() == null) {
return null;
@@ -189,6 +183,7 @@ private T getConvertedFullDocument(Document fullDocument) {
return (T) doGetConverted(fullDocument, CONVERTED_FULL_DOCUMENT_UPDATER);
}
+ @SuppressWarnings("NullAway")
private Object doGetConverted(Document fullDocument, AtomicReferenceFieldUpdater updater) {
Object result = updater.get(this);
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ChangeStreamOptions.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ChangeStreamOptions.java
index aaee3b76af..9c99b0e01f 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ChangeStreamOptions.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ChangeStreamOptions.java
@@ -23,9 +23,10 @@
import org.bson.BsonTimestamp;
import org.bson.BsonValue;
import org.bson.Document;
+import org.jspecify.annotations.Nullable;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.query.Collation;
-import org.springframework.lang.Nullable;
+import org.springframework.lang.Contract;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;
@@ -248,6 +249,7 @@ private ChangeStreamOptionsBuilder() {}
* @param collation must not be {@literal null} nor {@literal empty}.
* @return this.
*/
+ @Contract("_ -> this")
public ChangeStreamOptionsBuilder collation(Collation collation) {
Assert.notNull(collation, "Collation must not be null nor empty");
@@ -257,14 +259,12 @@ public ChangeStreamOptionsBuilder collation(Collation collation) {
}
/**
- * Set the filter to apply.
- *
+ * Set the filter to apply.
* Fields on aggregation expression root level are prefixed to map to fields contained in
* {@link ChangeStreamDocument#getFullDocument() fullDocument}. However {@literal operationType}, {@literal ns},
* {@literal documentKey} and {@literal fullDocument} are reserved words that will be omitted, and therefore taken
* as given, during the mapping procedure. You may want to have a look at the
- * structure of Change Events.
- *
+ * structure of Change Events.
* Use {@link org.springframework.data.mongodb.core.aggregation.TypedAggregation} to ensure filter expressions are
* mapped to domain type fields.
*
@@ -272,6 +272,7 @@ public ChangeStreamOptionsBuilder collation(Collation collation) {
* {@literal null}.
* @return this.
*/
+ @Contract("_ -> this")
public ChangeStreamOptionsBuilder filter(Aggregation filter) {
Assert.notNull(filter, "Filter must not be null");
@@ -286,6 +287,7 @@ public ChangeStreamOptionsBuilder filter(Aggregation filter) {
* @param filter must not be {@literal null} nor contain {@literal null} values.
* @return this.
*/
+ @Contract("_ -> this")
public ChangeStreamOptionsBuilder filter(Document... filter) {
Assert.noNullElements(filter, "Filter must not contain null values");
@@ -301,6 +303,7 @@ public ChangeStreamOptionsBuilder filter(Document... filter) {
* @param resumeToken must not be {@literal null}.
* @return this.
*/
+ @Contract("_ -> this")
public ChangeStreamOptionsBuilder resumeToken(BsonValue resumeToken) {
Assert.notNull(resumeToken, "ResumeToken must not be null");
@@ -330,6 +333,7 @@ public ChangeStreamOptionsBuilder returnFullDocumentOnUpdate() {
* @param lookup must not be {@literal null}.
* @return this.
*/
+ @Contract("_ -> this")
public ChangeStreamOptionsBuilder fullDocumentLookup(FullDocument lookup) {
Assert.notNull(lookup, "Lookup must not be null");
@@ -345,6 +349,7 @@ public ChangeStreamOptionsBuilder fullDocumentLookup(FullDocument lookup) {
* @return this.
* @since 4.0
*/
+ @Contract("_ -> this")
public ChangeStreamOptionsBuilder fullDocumentBeforeChangeLookup(FullDocumentBeforeChange lookup) {
Assert.notNull(lookup, "Lookup must not be null");
@@ -358,7 +363,7 @@ public ChangeStreamOptionsBuilder fullDocumentBeforeChangeLookup(FullDocumentBef
*
* @return this.
* @since 4.0
- * @see #fullDocumentBeforeChangeLookup(FullDocumentBeforeChange)
+ * @see #fullDocumentBeforeChangeLookup(FullDocumentBeforeChange)
*/
public ChangeStreamOptionsBuilder returnFullDocumentBeforeChange() {
return fullDocumentBeforeChangeLookup(FullDocumentBeforeChange.WHEN_AVAILABLE);
@@ -370,6 +375,7 @@ public ChangeStreamOptionsBuilder returnFullDocumentBeforeChange() {
* @param resumeTimestamp must not be {@literal null}.
* @return this.
*/
+ @Contract("_ -> this")
public ChangeStreamOptionsBuilder resumeAt(Instant resumeTimestamp) {
Assert.notNull(resumeTimestamp, "ResumeTimestamp must not be null");
@@ -385,6 +391,7 @@ public ChangeStreamOptionsBuilder resumeAt(Instant resumeTimestamp) {
* @return this.
* @since 2.2
*/
+ @Contract("_ -> this")
public ChangeStreamOptionsBuilder resumeAt(BsonTimestamp resumeTimestamp) {
Assert.notNull(resumeTimestamp, "ResumeTimestamp must not be null");
@@ -400,6 +407,7 @@ public ChangeStreamOptionsBuilder resumeAt(BsonTimestamp resumeTimestamp) {
* @return this.
* @since 2.2
*/
+ @Contract("_ -> this")
public ChangeStreamOptionsBuilder resumeAfter(BsonValue resumeToken) {
resumeToken(resumeToken);
@@ -415,6 +423,7 @@ public ChangeStreamOptionsBuilder resumeAfter(BsonValue resumeToken) {
* @return this.
* @since 2.2
*/
+ @Contract("_ -> this")
public ChangeStreamOptionsBuilder startAfter(BsonValue resumeToken) {
resumeToken(resumeToken);
@@ -426,6 +435,7 @@ public ChangeStreamOptionsBuilder startAfter(BsonValue resumeToken) {
/**
* @return the built {@link ChangeStreamOptions}
*/
+ @Contract("-> new")
public ChangeStreamOptions build() {
ChangeStreamOptions options = new ChangeStreamOptions();
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/CollectionCallback.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/CollectionCallback.java
index c142aca173..bf8be5ba69 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/CollectionCallback.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/CollectionCallback.java
@@ -16,8 +16,8 @@
package org.springframework.data.mongodb.core;
import org.bson.Document;
+import org.jspecify.annotations.Nullable;
import org.springframework.dao.DataAccessException;
-import org.springframework.lang.Nullable;
import com.mongodb.MongoException;
import com.mongodb.client.MongoCollection;
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/CollectionOptions.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/CollectionOptions.java
index d627ba2468..ff2c708aa9 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/CollectionOptions.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/CollectionOptions.java
@@ -19,6 +19,7 @@
import java.util.Optional;
import java.util.function.Function;
+import org.jspecify.annotations.Nullable;
import org.springframework.data.mongodb.core.mapping.Field;
import org.springframework.data.mongodb.core.query.Collation;
import org.springframework.data.mongodb.core.schema.MongoJsonSchema;
@@ -26,7 +27,7 @@
import org.springframework.data.mongodb.core.timeseries.GranularityDefinition;
import org.springframework.data.mongodb.core.validation.Validator;
import org.springframework.data.util.Optionals;
-import org.springframework.lang.Nullable;
+import org.springframework.lang.Contract;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
@@ -184,7 +185,7 @@ public CollectionOptions collation(@Nullable Collation collation) {
* @since 2.1
*/
public CollectionOptions schema(@Nullable MongoJsonSchema schema) {
- return validator(Validator.schema(schema));
+ return validator(schema != null ? Validator.schema(schema) : null);
}
/**
@@ -461,7 +462,8 @@ public static class ValidationOptions {
private final @Nullable ValidationLevel validationLevel;
private final @Nullable ValidationAction validationAction;
- public ValidationOptions(Validator validator, ValidationLevel validationLevel, ValidationAction validationAction) {
+ public ValidationOptions(@Nullable Validator validator, @Nullable ValidationLevel validationLevel,
+ @Nullable ValidationAction validationAction) {
this.validator = validator;
this.validationLevel = validationLevel;
@@ -483,6 +485,7 @@ public static ValidationOptions none() {
* @param validator can be {@literal null}.
* @return new instance of {@link ValidationOptions}.
*/
+ @Contract("_ -> new")
public ValidationOptions validator(@Nullable Validator validator) {
return new ValidationOptions(validator, validationLevel, validationAction);
}
@@ -493,6 +496,7 @@ public ValidationOptions validator(@Nullable Validator validator) {
* @param validationLevel can be {@literal null}.
* @return new instance of {@link ValidationOptions}.
*/
+ @Contract("_ -> new")
public ValidationOptions validationLevel(ValidationLevel validationLevel) {
return new ValidationOptions(validator, validationLevel, validationAction);
}
@@ -503,6 +507,7 @@ public ValidationOptions validationLevel(ValidationLevel validationLevel) {
* @param validationAction can be {@literal null}.
* @return new instance of {@link ValidationOptions}.
*/
+ @Contract("_ -> new")
public ValidationOptions validationAction(ValidationAction validationAction) {
return new ValidationOptions(validator, validationLevel, validationAction);
}
@@ -677,6 +682,7 @@ public static TimeSeriesOptions timeSeries(String timeField) {
* @param metaField must not be {@literal null}.
* @return new instance of {@link TimeSeriesOptions}.
*/
+ @Contract("_ -> new")
public TimeSeriesOptions metaField(String metaField) {
return new TimeSeriesOptions(timeField, metaField, granularity, expireAfter);
}
@@ -688,6 +694,7 @@ public TimeSeriesOptions metaField(String metaField) {
* @return new instance of {@link TimeSeriesOptions}.
* @see Granularity
*/
+ @Contract("_ -> new")
public TimeSeriesOptions granularity(GranularityDefinition granularity) {
return new TimeSeriesOptions(timeField, metaField, granularity, expireAfter);
}
@@ -700,6 +707,7 @@ public TimeSeriesOptions granularity(GranularityDefinition granularity) {
* @see com.mongodb.client.model.CreateCollectionOptions#expireAfter(long, java.util.concurrent.TimeUnit)
* @since 4.4
*/
+ @Contract("_ -> new")
public TimeSeriesOptions expireAfter(Duration ttl) {
return new TimeSeriesOptions(timeField, metaField, granularity, ttl);
}
@@ -715,8 +723,7 @@ public String getTimeField() {
* @return can be {@literal null}. Might be an {@literal empty} {@link String} as well, so maybe check via
* {@link org.springframework.util.StringUtils#hasText(String)}.
*/
- @Nullable
- public String getMetaField() {
+ public @Nullable String getMetaField() {
return metaField;
}
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/CollectionPreparerSupport.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/CollectionPreparerSupport.java
index 644a3a54d1..bdf0b90ee3 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/CollectionPreparerSupport.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/CollectionPreparerSupport.java
@@ -21,6 +21,7 @@
import java.util.function.Function;
import org.bson.Document;
+import org.jspecify.annotations.Nullable;
import com.mongodb.ReadConcern;
import com.mongodb.ReadPreference;
@@ -84,7 +85,7 @@ public boolean hasReadConcern() {
}
@Override
- public ReadConcern getReadConcern() {
+ public @Nullable ReadConcern getReadConcern() {
for (Object aware : sources) {
if (aware instanceof ReadConcernAware rca && rca.hasReadConcern()) {
@@ -108,7 +109,7 @@ public boolean hasReadPreference() {
}
@Override
- public ReadPreference getReadPreference() {
+ public @Nullable ReadPreference getReadPreference() {
for (Object aware : sources) {
if (aware instanceof ReadPreferenceAware rpa && rpa.hasReadPreference()) {
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/CountQuery.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/CountQuery.java
index 4fa6b3e97d..11d9f09afd 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/CountQuery.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/CountQuery.java
@@ -23,9 +23,9 @@
import java.util.Map;
import org.bson.Document;
+import org.jspecify.annotations.Nullable;
import org.springframework.data.geo.Point;
import org.springframework.data.mongodb.core.query.MetricConversion;
-import org.springframework.lang.Nullable;
import org.springframework.util.ObjectUtils;
/**
@@ -154,7 +154,7 @@ private Collection