Switch to JSpecify annotations

This commit updates the whole Spring Framework codebase to use JSpecify
annotations instead of Spring null-safety annotations with JSR 305
semantics.

JSpecify provides signficant enhancements such as properly defined
specifications, a canonical dependency with no split-package issue,
better tooling, better Kotlin integration and the capability to specify
generic type, array and varargs element null-safety. Generic type
null-safety is not defined by this commit yet and will be specified
later.

A key difference is that Spring null-safety annotations, following
JSR 305 semantics, apply to fields, parameters and return values,
while JSpecify annotations apply to type usages. That's why this
commit moves nullability annotations closer to the type for fields
and return values.

See gh-28797
This commit is contained in:
Sébastien Deleuze
2024-12-03 15:22:37 +01:00
parent fcb8aed03f
commit bc5d771a06
3459 changed files with 14118 additions and 22059 deletions

View File

@@ -17,9 +17,9 @@
package org.springframework.r2dbc;
import io.r2dbc.spi.R2dbcException;
import org.jspecify.annotations.Nullable;
import org.springframework.dao.InvalidDataAccessResourceUsageException;
import org.springframework.lang.Nullable;
/**
* Exception thrown when SQL specified is invalid. Such exceptions always have a
@@ -53,8 +53,7 @@ public class BadSqlGrammarException extends InvalidDataAccessResourceUsageExcept
/**
* Return the wrapped {@link R2dbcException}.
*/
@Nullable
public R2dbcException getR2dbcException() {
public @Nullable R2dbcException getR2dbcException() {
return (R2dbcException) getCause();
}

View File

@@ -17,9 +17,9 @@
package org.springframework.r2dbc;
import io.r2dbc.spi.R2dbcException;
import org.jspecify.annotations.Nullable;
import org.springframework.dao.UncategorizedDataAccessException;
import org.springframework.lang.Nullable;
/**
* Exception thrown when we can't classify a {@link R2dbcException} into
@@ -32,8 +32,7 @@ import org.springframework.lang.Nullable;
public class UncategorizedR2dbcException extends UncategorizedDataAccessException {
/** SQL that led to the problem. */
@Nullable
private final String sql;
private final @Nullable String sql;
/**
@@ -51,16 +50,14 @@ public class UncategorizedR2dbcException extends UncategorizedDataAccessExceptio
/**
* Return the wrapped {@link R2dbcException}.
*/
@Nullable
public R2dbcException getR2dbcException() {
public @Nullable R2dbcException getR2dbcException() {
return (R2dbcException) getCause();
}
/**
* Return the SQL that led to the problem (if known).
*/
@Nullable
public String getSql() {
public @Nullable String getSql() {
return this.sql;
}

View File

@@ -31,6 +31,7 @@ import io.r2dbc.spi.R2dbcTimeoutException;
import io.r2dbc.spi.R2dbcTransientException;
import io.r2dbc.spi.R2dbcTransientResourceException;
import io.r2dbc.spi.Wrapped;
import org.jspecify.annotations.Nullable;
import reactor.core.publisher.Mono;
import org.springframework.core.Ordered;
@@ -43,7 +44,6 @@ import org.springframework.dao.PermissionDeniedDataAccessException;
import org.springframework.dao.PessimisticLockingFailureException;
import org.springframework.dao.QueryTimeoutException;
import org.springframework.dao.TransientDataAccessResourceException;
import org.springframework.lang.Nullable;
import org.springframework.r2dbc.BadSqlGrammarException;
import org.springframework.r2dbc.UncategorizedR2dbcException;
import org.springframework.transaction.NoTransactionException;

View File

@@ -18,8 +18,8 @@ package org.springframework.r2dbc.connection;
import io.r2dbc.spi.Connection;
import io.r2dbc.spi.ConnectionFactory;
import org.jspecify.annotations.Nullable;
import org.springframework.lang.Nullable;
import org.springframework.transaction.support.ResourceHolderSupport;
import org.springframework.util.Assert;
@@ -48,8 +48,7 @@ public class ConnectionHolder extends ResourceHolderSupport {
static final String SAVEPOINT_NAME_PREFIX = "SAVEPOINT_";
@Nullable
private Connection currentConnection;
private @Nullable Connection currentConnection;
private boolean transactionActive;

View File

@@ -24,10 +24,10 @@ import io.r2dbc.spi.IsolationLevel;
import io.r2dbc.spi.Option;
import io.r2dbc.spi.R2dbcException;
import io.r2dbc.spi.Result;
import org.jspecify.annotations.Nullable;
import reactor.core.publisher.Mono;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.lang.Nullable;
import org.springframework.transaction.CannotCreateTransactionException;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.reactive.AbstractReactiveTransactionManager;
@@ -83,8 +83,7 @@ import org.springframework.util.Assert;
@SuppressWarnings("serial")
public class R2dbcTransactionManager extends AbstractReactiveTransactionManager implements InitializingBean {
@Nullable
private ConnectionFactory connectionFactory;
private @Nullable ConnectionFactory connectionFactory;
private boolean enforceReadOnly = false;
@@ -123,8 +122,7 @@ public class R2dbcTransactionManager extends AbstractReactiveTransactionManager
/**
* Return the R2DBC {@link ConnectionFactory} that this instance manages transactions for.
*/
@Nullable
public ConnectionFactory getConnectionFactory() {
public @Nullable ConnectionFactory getConnectionFactory() {
return this.connectionFactory;
}
@@ -415,8 +413,7 @@ public class R2dbcTransactionManager extends AbstractReactiveTransactionManager
* should remain {@link TransactionDefinition#ISOLATION_DEFAULT default}.
* @see TransactionDefinition#getIsolationLevel()
*/
@Nullable
protected IsolationLevel resolveIsolationLevel(int isolationLevel) {
protected @Nullable IsolationLevel resolveIsolationLevel(int isolationLevel) {
return switch (isolationLevel) {
case TransactionDefinition.ISOLATION_READ_COMMITTED -> IsolationLevel.READ_COMMITTED;
case TransactionDefinition.ISOLATION_READ_UNCOMMITTED -> IsolationLevel.READ_UNCOMMITTED;
@@ -448,13 +445,11 @@ public class R2dbcTransactionManager extends AbstractReactiveTransactionManager
@SuppressWarnings("unchecked")
@Override
@Nullable
public <T> T getAttribute(Option<T> option) {
public <T> @Nullable T getAttribute(Option<T> option) {
return (T) doGetValue(option);
}
@Nullable
private Object doGetValue(Option<?> option) {
private @Nullable Object doGetValue(Option<?> option) {
if (io.r2dbc.spi.TransactionDefinition.ISOLATION_LEVEL.equals(option)) {
return this.isolationLevel;
}
@@ -491,15 +486,13 @@ public class R2dbcTransactionManager extends AbstractReactiveTransactionManager
*/
private static class ConnectionFactoryTransactionObject {
@Nullable
private ConnectionHolder connectionHolder;
private @Nullable ConnectionHolder connectionHolder;
private boolean newConnectionHolder;
private boolean mustRestoreAutoCommit;
@Nullable
private String savepointName;
private @Nullable String savepointName;
void setConnectionHolder(@Nullable ConnectionHolder connectionHolder, boolean newConnectionHolder) {
setConnectionHolder(connectionHolder);

View File

@@ -27,11 +27,11 @@ import io.r2dbc.spi.ConnectionFactories;
import io.r2dbc.spi.ConnectionFactory;
import io.r2dbc.spi.ConnectionFactoryMetadata;
import io.r2dbc.spi.Wrapped;
import org.jspecify.annotations.Nullable;
import org.reactivestreams.Publisher;
import reactor.core.publisher.Mono;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
@@ -70,15 +70,13 @@ public class SingleConnectionFactory extends DelegatingConnectionFactory
private boolean suppressClose;
/** Override auto-commit state?. */
@Nullable
private Boolean autoCommit;
private @Nullable Boolean autoCommit;
/** Wrapped Connection. */
private final AtomicReference<Connection> target = new AtomicReference<>();
/** Proxy Connection. */
@Nullable
private Connection connection;
private @Nullable Connection connection;
private final Mono<? extends Connection> connectionEmitter;
@@ -164,8 +162,7 @@ public class SingleConnectionFactory extends DelegatingConnectionFactory
* be overridden.
* @return the "autoCommit" value, or {@code null} if none to be applied
*/
@Nullable
protected Boolean getAutoCommitValue() {
protected @Nullable Boolean getAutoCommitValue() {
return this.autoCommit;
}
@@ -251,8 +248,7 @@ public class SingleConnectionFactory extends DelegatingConnectionFactory
}
@Override
@Nullable
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
public @Nullable Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return switch (method.getName()) {
// Only consider equal when proxies are identical.
case "equals" -> proxy == args[0];

View File

@@ -24,9 +24,9 @@ import java.lang.reflect.Proxy;
import io.r2dbc.spi.Connection;
import io.r2dbc.spi.ConnectionFactory;
import io.r2dbc.spi.Wrapped;
import org.jspecify.annotations.Nullable;
import reactor.core.publisher.Mono;
import org.springframework.lang.Nullable;
import org.springframework.util.ReflectionUtils;
/**
@@ -129,8 +129,7 @@ public class TransactionAwareConnectionFactoryProxy extends DelegatingConnection
}
@Override
@Nullable
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
public @Nullable Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (ReflectionUtils.isObjectMethod(method)) {
if (ReflectionUtils.isToStringMethod(method)) {
return proxyToString(proxy);

View File

@@ -17,10 +17,10 @@
package org.springframework.r2dbc.connection.init;
import io.r2dbc.spi.ConnectionFactory;
import org.jspecify.annotations.Nullable;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
@@ -36,14 +36,11 @@ import org.springframework.util.Assert;
*/
public class ConnectionFactoryInitializer implements InitializingBean, DisposableBean {
@Nullable
private ConnectionFactory connectionFactory;
private @Nullable ConnectionFactory connectionFactory;
@Nullable
private DatabasePopulator databasePopulator;
private @Nullable DatabasePopulator databasePopulator;
@Nullable
private DatabasePopulator databaseCleaner;
private @Nullable DatabasePopulator databaseCleaner;
private boolean enabled = true;

View File

@@ -22,6 +22,7 @@ import java.util.Arrays;
import java.util.List;
import io.r2dbc.spi.Connection;
import org.jspecify.annotations.Nullable;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
@@ -29,7 +30,6 @@ import org.springframework.core.io.Resource;
import org.springframework.core.io.buffer.DataBufferFactory;
import org.springframework.core.io.buffer.DefaultDataBufferFactory;
import org.springframework.core.io.support.EncodedResource;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
@@ -59,8 +59,7 @@ public class ResourceDatabasePopulator implements DatabasePopulator {
List<Resource> scripts = new ArrayList<>();
@Nullable
private Charset sqlScriptEncoding;
private @Nullable Charset sqlScriptEncoding;
private String separator = ScriptUtils.DEFAULT_STATEMENT_SEPARATOR;

View File

@@ -16,8 +16,9 @@
package org.springframework.r2dbc.connection.init;
import org.jspecify.annotations.Nullable;
import org.springframework.dao.DataAccessException;
import org.springframework.lang.Nullable;
/**
* Root of the hierarchy of data access exceptions that are related to processing

View File

@@ -16,8 +16,9 @@
package org.springframework.r2dbc.connection.init;
import org.jspecify.annotations.Nullable;
import org.springframework.core.io.support.EncodedResource;
import org.springframework.lang.Nullable;
/**
* Thrown by {@link ScriptUtils} if an SQL script cannot be properly parsed.

View File

@@ -29,6 +29,7 @@ import io.r2dbc.spi.Connection;
import io.r2dbc.spi.Result;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jspecify.annotations.Nullable;
import org.reactivestreams.Publisher;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
@@ -38,7 +39,6 @@ import org.springframework.core.io.buffer.DataBufferFactory;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.core.io.buffer.DefaultDataBufferFactory;
import org.springframework.core.io.support.EncodedResource;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

View File

@@ -1,9 +1,7 @@
/**
* Provides extensible support for initializing databases through scripts.
*/
@NonNullApi
@NonNullFields
@NullMarked
package org.springframework.r2dbc.connection.init;
import org.springframework.lang.NonNullApi;
import org.springframework.lang.NonNullFields;
import org.jspecify.annotations.NullMarked;

View File

@@ -21,10 +21,10 @@ import java.util.Map;
import io.r2dbc.spi.Connection;
import io.r2dbc.spi.ConnectionFactory;
import io.r2dbc.spi.ConnectionFactoryMetadata;
import org.jspecify.annotations.Nullable;
import reactor.core.publisher.Mono;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
@@ -54,21 +54,17 @@ public abstract class AbstractRoutingConnectionFactory implements ConnectionFact
private static final Object FALLBACK_MARKER = new Object();
@Nullable
private Map<?, ?> targetConnectionFactories;
private @Nullable Map<?, ?> targetConnectionFactories;
@Nullable
private Object defaultTargetConnectionFactory;
private @Nullable Object defaultTargetConnectionFactory;
private boolean lenientFallback = true;
private ConnectionFactoryLookup connectionFactoryLookup = new MapConnectionFactoryLookup();
@Nullable
private Map<Object, ConnectionFactory> resolvedConnectionFactories;
private @Nullable Map<Object, ConnectionFactory> resolvedConnectionFactories;
@Nullable
private ConnectionFactory resolvedDefaultConnectionFactory;
private @Nullable ConnectionFactory resolvedDefaultConnectionFactory;
/**

View File

@@ -17,11 +17,11 @@
package org.springframework.r2dbc.connection.lookup;
import io.r2dbc.spi.ConnectionFactory;
import org.jspecify.annotations.Nullable;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
@@ -37,8 +37,7 @@ import org.springframework.util.Assert;
*/
public class BeanFactoryConnectionFactoryLookup implements ConnectionFactoryLookup, BeanFactoryAware {
@Nullable
private BeanFactory beanFactory;
private @Nullable BeanFactory beanFactory;
/**

View File

@@ -1,9 +1,7 @@
/**
* Provides a strategy for looking up R2DBC ConnectionFactories by name.
*/
@NonNullApi
@NonNullFields
@NullMarked
package org.springframework.r2dbc.connection.lookup;
import org.springframework.lang.NonNullApi;
import org.springframework.lang.NonNullFields;
import org.jspecify.annotations.NullMarked;

View File

@@ -3,9 +3,7 @@
* a ReactiveTransactionManager for a single ConnectionFactory,
* and various simple ConnectionFactory implementations.
*/
@NonNullApi
@NonNullFields
@NullMarked
package org.springframework.r2dbc.connection;
import org.springframework.lang.NonNullApi;
import org.springframework.lang.NonNullFields;
import org.jspecify.annotations.NullMarked;

View File

@@ -29,13 +29,13 @@ import io.r2dbc.spi.Readable;
import io.r2dbc.spi.ReadableMetadata;
import io.r2dbc.spi.Row;
import io.r2dbc.spi.RowMetadata;
import org.jspecify.annotations.Nullable;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeanWrapperImpl;
import org.springframework.beans.TypeConverter;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.support.DefaultConversionService;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
@@ -235,8 +235,7 @@ public class BeanPropertyRowMapper<T> implements Function<Readable, T> {
* @see Readable#get(int, Class)
* @see Readable#get(int)
*/
@Nullable
protected Object getItemValue(Readable readable, int itemIndex, Class<?> paramType) {
protected @Nullable Object getItemValue(Readable readable, int itemIndex, Class<?> paramType) {
try {
return readable.get(itemIndex, paramType);
}

View File

@@ -23,8 +23,8 @@ import java.util.function.BiFunction;
import io.r2dbc.spi.ColumnMetadata;
import io.r2dbc.spi.Row;
import io.r2dbc.spi.RowMetadata;
import org.jspecify.annotations.Nullable;
import org.springframework.lang.Nullable;
import org.springframework.util.LinkedCaseInsensitiveMap;
/**
@@ -95,8 +95,7 @@ public class ColumnMapRowMapper implements BiFunction<Row, RowMetadata, Map<Stri
* @param index is the column index
* @return the Object returned
*/
@Nullable
protected Object getColumnValue(Row row, int index) {
protected @Nullable Object getColumnValue(Row row, int index) {
return row.get(index);
}

View File

@@ -45,13 +45,13 @@ import io.r2dbc.spi.Statement;
import io.r2dbc.spi.Wrapped;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jspecify.annotations.Nullable;
import org.reactivestreams.Publisher;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import org.springframework.beans.BeanUtils;
import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.lang.Nullable;
import org.springframework.r2dbc.connection.ConnectionFactoryUtils;
import org.springframework.r2dbc.core.binding.BindMarkersFactory;
import org.springframework.r2dbc.core.binding.BindTarget;
@@ -82,8 +82,7 @@ final class DefaultDatabaseClient implements DatabaseClient {
private final ExecuteFunction executeFunction;
@Nullable
private final NamedParameterExpander namedParameterExpander;
private final @Nullable NamedParameterExpander namedParameterExpander;
DefaultDatabaseClient(BindMarkersFactory bindMarkersFactory, ConnectionFactory connectionFactory,
@@ -208,8 +207,7 @@ final class DefaultDatabaseClient implements DatabaseClient {
* @return the SQL string, or {@code null}
* @see SqlProvider
*/
@Nullable
private static String getSql(Object object) {
private static @Nullable String getSql(Object object) {
if (object instanceof SqlProvider sqlProvider) {
return sqlProvider.getSql();
}
@@ -475,8 +473,7 @@ final class DefaultDatabaseClient implements DatabaseClient {
return new MapBindParameterSource(namedBindings);
}
@Nullable
private Parameter getParameter(Map<String, Parameter> remainderByName,
private @Nullable Parameter getParameter(Map<String, Parameter> remainderByName,
Map<Integer, Parameter> remainderByIndex, List<String> parameterNames, String parameterName) {
if (this.byName.containsKey(parameterName)) {
@@ -530,8 +527,7 @@ final class DefaultDatabaseClient implements DatabaseClient {
}
@Override
@Nullable
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
public @Nullable Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return switch (method.getName()) {
// Only consider equal when proxies are identical.
case "equals" -> proxy == args[0];

View File

@@ -20,8 +20,8 @@ import java.util.function.Consumer;
import io.r2dbc.spi.ConnectionFactory;
import io.r2dbc.spi.Statement;
import org.jspecify.annotations.Nullable;
import org.springframework.lang.Nullable;
import org.springframework.r2dbc.core.binding.BindMarkersFactory;
import org.springframework.r2dbc.core.binding.BindMarkersFactoryResolver;
import org.springframework.util.Assert;
@@ -34,11 +34,9 @@ import org.springframework.util.Assert;
*/
class DefaultDatabaseClientBuilder implements DatabaseClient.Builder {
@Nullable
private BindMarkersFactory bindMarkers;
private @Nullable BindMarkersFactory bindMarkers;
@Nullable
private ConnectionFactory connectionFactory;
private @Nullable ConnectionFactory connectionFactory;
private ExecuteFunction executeFunction = Statement::execute;

View File

@@ -19,8 +19,7 @@ package org.springframework.r2dbc.core;
import java.util.function.Function;
import io.r2dbc.spi.Connection;
import org.springframework.lang.Nullable;
import org.jspecify.annotations.Nullable;
/**
* A {@link ConnectionFunction} that delegates to a {@code SqlProvider} and a plain
@@ -48,9 +47,8 @@ final class DelegateConnectionFunction<R> implements ConnectionFunction<R> {
return this.function.apply(t);
}
@Nullable
@Override
public String getSql() {
public @Nullable String getSql() {
return this.sql.getSql();
}
}

View File

@@ -26,9 +26,9 @@ import java.util.Set;
import java.util.TreeMap;
import io.r2dbc.spi.Parameter;
import org.jspecify.annotations.Nullable;
import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.lang.Nullable;
import org.springframework.r2dbc.core.binding.BindMarker;
import org.springframework.r2dbc.core.binding.BindMarkers;
import org.springframework.r2dbc.core.binding.BindMarkersFactory;
@@ -460,8 +460,7 @@ abstract class NamedParameterUtils {
return param;
}
@Nullable
List<NamedParameter> getMarker(String name) {
@Nullable List<NamedParameter> getMarker(String name) {
return this.references.get(name);
}
@@ -566,8 +565,7 @@ abstract class NamedParameterUtils {
}
}
@Nullable
List<BindMarker> getBindMarkers(String identifier) {
@Nullable List<BindMarker> getBindMarkers(String identifier) {
List<NamedParameters.NamedParameter> parameters = this.parameters.getMarker(identifier);
if (parameters == null) {
return null;

View File

@@ -16,7 +16,8 @@
package org.springframework.r2dbc.core;
import org.springframework.lang.Nullable;
import org.jspecify.annotations.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;
@@ -32,8 +33,7 @@ import org.springframework.util.ObjectUtils;
@Deprecated(since = "6.0")
public final class Parameter {
@Nullable
private final Object value;
private final @Nullable Object value;
private final Class<?> type;
@@ -79,8 +79,7 @@ public final class Parameter {
* Return the column value (can be {@code null}).
* @see #hasValue()
*/
@Nullable
public Object getValue() {
public @Nullable Object getValue() {
return this.value;
}

View File

@@ -22,9 +22,9 @@ import java.util.function.Supplier;
import io.r2dbc.spi.Connection;
import io.r2dbc.spi.Result;
import io.r2dbc.spi.Statement;
import org.jspecify.annotations.Nullable;
import reactor.core.publisher.Flux;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
@@ -46,8 +46,7 @@ final class ResultFunction implements ConnectionFunction<Flux<Result>> {
final StatementFilterFunction filterFunction;
final ExecuteFunction executeFunction;
@Nullable
String resolvedSql = null;
@Nullable String resolvedSql = null;
ResultFunction(Supplier<String> sqlSupplier, BiFunction<Connection, String, Statement> statementFunction, StatementFilterFunction filterFunction, ExecuteFunction executeFunction) {
this.sqlSupplier = sqlSupplier;
@@ -66,9 +65,8 @@ final class ResultFunction implements ConnectionFunction<Flux<Result>> {
.cast(Result.class).checkpoint("SQL \"" + sql + "\" [DatabaseClient]");
}
@Nullable
@Override
public String getSql() {
public @Nullable String getSql() {
return this.resolvedSql;
}
}

View File

@@ -16,7 +16,7 @@
package org.springframework.r2dbc.core;
import org.springframework.lang.Nullable;
import org.jspecify.annotations.Nullable;
/**
* Interface to be implemented by objects that can provide SQL strings.
@@ -35,7 +35,6 @@ public interface SqlProvider {
* typically the SQL used for creating statements.
* @return the SQL string, or {@code null} if not available
*/
@Nullable
String getSql();
@Nullable String getSql();
}

View File

@@ -22,10 +22,10 @@ import java.util.Map;
import io.r2dbc.spi.ConnectionFactory;
import io.r2dbc.spi.ConnectionFactoryMetadata;
import org.jspecify.annotations.Nullable;
import org.springframework.core.io.support.SpringFactoriesLoader;
import org.springframework.dao.NonTransientDataAccessException;
import org.springframework.lang.Nullable;
import org.springframework.util.LinkedCaseInsensitiveMap;
/**
@@ -83,8 +83,7 @@ public final class BindMarkersFactoryResolver {
* @return the {@link BindMarkersFactory} if the {@link BindMarkerFactoryProvider}
* can provide a bind marker factory object, otherwise {@code null}
*/
@Nullable
BindMarkersFactory getBindMarkers(ConnectionFactory connectionFactory);
@Nullable BindMarkersFactory getBindMarkers(ConnectionFactory connectionFactory);
}
@@ -129,8 +128,7 @@ public final class BindMarkersFactoryResolver {
@Override
@Nullable
public BindMarkersFactory getBindMarkers(ConnectionFactory connectionFactory) {
public @Nullable BindMarkersFactory getBindMarkers(ConnectionFactory connectionFactory) {
ConnectionFactoryMetadata metadata = connectionFactory.getMetadata();
BindMarkersFactory r2dbcDialect = BUILTIN.get(metadata.getName());
if (r2dbcDialect != null) {

View File

@@ -26,9 +26,9 @@ import java.util.Spliterator;
import java.util.function.Consumer;
import io.r2dbc.spi.Statement;
import org.jspecify.annotations.NonNull;
import org.jspecify.annotations.Nullable;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
@@ -178,8 +178,7 @@ public class Bindings implements Iterable<Bindings.Binding> {
* @return the value of this binding
* (can be {@code null} if this is a {@code NULL} binding)
*/
@Nullable
public abstract Object getValue();
public abstract @Nullable Object getValue();
/**
* Apply the binding to a {@link BindTarget}.
@@ -207,8 +206,7 @@ public class Bindings implements Iterable<Bindings.Binding> {
}
@Override
@NonNull
public Object getValue() {
public @NonNull Object getValue() {
return this.value;
}
@@ -237,8 +235,7 @@ public class Bindings implements Iterable<Bindings.Binding> {
}
@Override
@Nullable
public Object getValue() {
public @Nullable Object getValue() {
return null;
}

View File

@@ -1,9 +1,7 @@
/**
* Classes providing an abstraction over SQL bind markers.
*/
@NonNullApi
@NonNullFields
@NullMarked
package org.springframework.r2dbc.core.binding;
import org.springframework.lang.NonNullApi;
import org.springframework.lang.NonNullFields;
import org.jspecify.annotations.NullMarked;

View File

@@ -1,9 +1,7 @@
/**
* Core domain types around DatabaseClient.
*/
@NonNullApi
@NonNullFields
@NullMarked
package org.springframework.r2dbc.core;
import org.springframework.lang.NonNullApi;
import org.springframework.lang.NonNullFields;
import org.jspecify.annotations.NullMarked;

View File

@@ -13,9 +13,7 @@
* dependencies into application code.
* </ul>
*/
@NonNullApi
@NonNullFields
@NullMarked
package org.springframework.r2dbc;
import org.springframework.lang.NonNullApi;
import org.springframework.lang.NonNullFields;
import org.jspecify.annotations.NullMarked;

View File

@@ -29,6 +29,7 @@ import io.r2dbc.spi.test.MockColumnMetadata;
import io.r2dbc.spi.test.MockResult;
import io.r2dbc.spi.test.MockRow;
import io.r2dbc.spi.test.MockRowMetadata;
import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.InOrder;
@@ -43,7 +44,6 @@ import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;
import org.springframework.dao.IncorrectResultSizeDataAccessException;
import org.springframework.lang.Nullable;
import org.springframework.r2dbc.core.binding.BindMarkersFactory;
import org.springframework.r2dbc.core.binding.BindTarget;
@@ -488,7 +488,7 @@ class DefaultDatabaseClientTests {
* Mocks a {@link Result} with a single column "name" and a single row if a non-null
* row is provided.
*/
private MockResult mockSingleColumnResult(@Nullable MockRow.Builder row) {
private MockResult mockSingleColumnResult(MockRow.@Nullable Builder row) {
MockResult.Builder resultBuilder = MockResult.builder();
if (row != null) {
MockRowMetadata metadata = MockRowMetadata.builder().columnMetadata(