diff --git a/spring-data-cassandra/pom.xml b/spring-data-cassandra/pom.xml index a57987561..7f28c7f2b 100644 --- a/spring-data-cassandra/pom.xml +++ b/spring-data-cassandra/pom.xml @@ -227,6 +227,11 @@ kotlinx-coroutines-reactor true + + org.jspecify + jspecify + 1.0.0 + io.mockk diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/CassandraAuthenticationException.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/CassandraAuthenticationException.java index 593f6ad8e..ae130ed02 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/CassandraAuthenticationException.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/CassandraAuthenticationException.java @@ -28,7 +28,7 @@ import com.datastax.oss.driver.api.core.metadata.EndPoint; */ public class CassandraAuthenticationException extends PermissionDeniedDataAccessException { - @Serial private static final long serialVersionUID = 8556304586797273927L; + private static final @Serial long serialVersionUID = 8556304586797273927L; private final EndPoint host; diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/CassandraConnectionFailureException.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/CassandraConnectionFailureException.java index d1187934b..90f316bfd 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/CassandraConnectionFailureException.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/CassandraConnectionFailureException.java @@ -31,7 +31,7 @@ import com.datastax.oss.driver.api.core.metadata.Node; */ public class CassandraConnectionFailureException extends DataAccessResourceFailureException { - @Serial private static final long serialVersionUID = 6299912054261646552L; + private static final @Serial long serialVersionUID = 6299912054261646552L; private final Map messagesByHost; diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/CassandraInsufficientReplicasAvailableException.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/CassandraInsufficientReplicasAvailableException.java index 3d29aec69..f13ad91db 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/CassandraInsufficientReplicasAvailableException.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/CassandraInsufficientReplicasAvailableException.java @@ -26,7 +26,7 @@ import org.springframework.dao.TransientDataAccessException; */ public class CassandraInsufficientReplicasAvailableException extends TransientDataAccessException { - @Serial private static final long serialVersionUID = 6415130674604814905L; + private static final @Serial long serialVersionUID = 6415130674604814905L; private int numberRequired; private int numberAlive; diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/CassandraInternalException.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/CassandraInternalException.java index 91052b4bc..4a02ce23c 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/CassandraInternalException.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/CassandraInternalException.java @@ -26,7 +26,7 @@ import org.springframework.dao.DataAccessException; */ public class CassandraInternalException extends DataAccessException { - @Serial private static final long serialVersionUID = 433061676465346338L; + private static final @Serial long serialVersionUID = 433061676465346338L; /** * Constructor for {@link CassandraInternalException}. diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/CassandraInvalidConfigurationInQueryException.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/CassandraInvalidConfigurationInQueryException.java index 3e99a8b1c..3240f05dc 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/CassandraInvalidConfigurationInQueryException.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/CassandraInvalidConfigurationInQueryException.java @@ -27,7 +27,7 @@ import org.springframework.dao.InvalidDataAccessApiUsageException; */ public class CassandraInvalidConfigurationInQueryException extends InvalidDataAccessApiUsageException { - @Serial private static final long serialVersionUID = 4594321191806182918L; + private static final @Serial long serialVersionUID = 4594321191806182918L; /** * Constructor for {@link CassandraInvalidConfigurationInQueryException}. diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/CassandraInvalidQueryException.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/CassandraInvalidQueryException.java index efb69682a..ff7c1a296 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/CassandraInvalidQueryException.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/CassandraInvalidQueryException.java @@ -26,7 +26,7 @@ import org.springframework.dao.InvalidDataAccessApiUsageException; */ public class CassandraInvalidQueryException extends InvalidDataAccessApiUsageException { - @Serial private static final long serialVersionUID = 4594321191806182918L; + private static final @Serial long serialVersionUID = 4594321191806182918L; /** * Constructor for {@link CassandraInvalidQueryException}. diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/CassandraKeyspaceExistsException.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/CassandraKeyspaceExistsException.java index f2a4b6145..449200867 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/CassandraKeyspaceExistsException.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/CassandraKeyspaceExistsException.java @@ -24,7 +24,7 @@ import java.io.Serial; */ public class CassandraKeyspaceExistsException extends CassandraSchemaElementExistsException { - @Serial private static final long serialVersionUID = 6032967419751410352L; + private static final @Serial long serialVersionUID = 6032967419751410352L; /** * Constructor for {@link CassandraKeyspaceExistsException}. @@ -37,6 +37,7 @@ public class CassandraKeyspaceExistsException extends CassandraSchemaElementExis super(keyspaceName, ElementType.KEYSPACE, msg, cause); } + @SuppressWarnings("NullAway") public String getKeyspaceName() { return getElementName(); } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/CassandraManagedTypes.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/CassandraManagedTypes.java index 439f7e42f..9c7e97ddc 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/CassandraManagedTypes.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/CassandraManagedTypes.java @@ -80,4 +80,5 @@ public final class CassandraManagedTypes implements ManagedTypes { public void forEach(Consumer> action) { delegate.forEach(action); } + } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/CassandraQuerySyntaxException.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/CassandraQuerySyntaxException.java index c6a1fe0db..12fad087a 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/CassandraQuerySyntaxException.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/CassandraQuerySyntaxException.java @@ -26,7 +26,7 @@ import org.springframework.dao.InvalidDataAccessApiUsageException; */ public class CassandraQuerySyntaxException extends InvalidDataAccessApiUsageException { - @Serial private static final long serialVersionUID = 4398474399882434154L; + private static final @Serial long serialVersionUID = 4398474399882434154L; /** * Constructor for {@link CassandraQuerySyntaxException}. diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/CassandraReadTimeoutException.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/CassandraReadTimeoutException.java index b0a5f5d2e..ce19e28ff 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/CassandraReadTimeoutException.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/CassandraReadTimeoutException.java @@ -27,7 +27,7 @@ import org.springframework.dao.QueryTimeoutException; */ public class CassandraReadTimeoutException extends QueryTimeoutException { - @Serial private static final long serialVersionUID = -787022307935203387L; + private static final @Serial long serialVersionUID = -787022307935203387L; private final boolean wasDataPresent; diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/CassandraSchemaElementExistsException.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/CassandraSchemaElementExistsException.java index fecdc0899..fcd520feb 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/CassandraSchemaElementExistsException.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/CassandraSchemaElementExistsException.java @@ -17,8 +17,8 @@ package org.springframework.data.cassandra; import java.io.Serial; +import org.jspecify.annotations.Nullable; import org.springframework.dao.NonTransientDataAccessException; -import org.springframework.lang.Nullable; /** * Spring data access exception for when Cassandra schema element being created already exists. @@ -28,15 +28,15 @@ import org.springframework.lang.Nullable; */ public class CassandraSchemaElementExistsException extends NonTransientDataAccessException { - @Serial private static final long serialVersionUID = 7798361273692300162L; + private static final @Serial long serialVersionUID = 7798361273692300162L; @Deprecated public enum ElementType { KEYSPACE, TABLE, COLUMN, INDEX } - private String elementName; - private ElementType elementType; + private @Nullable String elementName; + private @Nullable ElementType elementType; /** * Constructor for {@link CassandraSchemaElementExistsException}. @@ -65,14 +65,13 @@ public class CassandraSchemaElementExistsException extends NonTransientDataAcces } @Deprecated - @Nullable - public String getElementName() { + public @Nullable String getElementName() { return elementName; } @Deprecated - @Nullable - public ElementType getElementType() { + public @Nullable ElementType getElementType() { return elementType; } + } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/CassandraTableExistsException.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/CassandraTableExistsException.java index ef1db4e87..cb6d23978 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/CassandraTableExistsException.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/CassandraTableExistsException.java @@ -24,7 +24,7 @@ import java.io.Serial; */ public class CassandraTableExistsException extends CassandraSchemaElementExistsException { - @Serial private static final long serialVersionUID = 6032967419751410352L; + private static final @Serial long serialVersionUID = 6032967419751410352L; /** * Constructor for {@link CassandraTableExistsException}. @@ -37,6 +37,7 @@ public class CassandraTableExistsException extends CassandraSchemaElementExistsE super(tableName, ElementType.TABLE, msg, cause); } + @SuppressWarnings("NullAway") public String getTableName() { return getElementName(); } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/CassandraTraceRetrievalException.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/CassandraTraceRetrievalException.java index cce98d085..e5668ca98 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/CassandraTraceRetrievalException.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/CassandraTraceRetrievalException.java @@ -26,7 +26,7 @@ import org.springframework.dao.TransientDataAccessException; */ public class CassandraTraceRetrievalException extends TransientDataAccessException { - @Serial private static final long serialVersionUID = -3163557220324700239L; + private static final @Serial long serialVersionUID = -3163557220324700239L; /** * Constructor for {@link CassandraTraceRetrievalException}. diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/CassandraTruncateException.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/CassandraTruncateException.java index fc803fdd5..4700655b2 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/CassandraTruncateException.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/CassandraTruncateException.java @@ -26,7 +26,7 @@ import org.springframework.dao.TransientDataAccessException; */ public class CassandraTruncateException extends TransientDataAccessException { - @Serial private static final long serialVersionUID = 5730642491362430311L; + private static final @Serial long serialVersionUID = 5730642491362430311L; /** * Constructor for {@link CassandraTruncateException}. diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/CassandraTypeMismatchException.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/CassandraTypeMismatchException.java index d4b6e250d..3c82029e9 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/CassandraTypeMismatchException.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/CassandraTypeMismatchException.java @@ -26,7 +26,7 @@ import org.springframework.dao.TypeMismatchDataAccessException; */ public class CassandraTypeMismatchException extends TypeMismatchDataAccessException { - @Serial private static final long serialVersionUID = -7420058975444905629L; + private static final @Serial long serialVersionUID = -7420058975444905629L; /** * Constructor for {@link CassandraTypeMismatchException}. diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/CassandraUnauthorizedException.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/CassandraUnauthorizedException.java index c49e88657..837e3aea4 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/CassandraUnauthorizedException.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/CassandraUnauthorizedException.java @@ -26,7 +26,7 @@ import org.springframework.dao.PermissionDeniedDataAccessException; */ public class CassandraUnauthorizedException extends PermissionDeniedDataAccessException { - @Serial private static final long serialVersionUID = 4618185356687726647L; + private static final @Serial long serialVersionUID = 4618185356687726647L; /** * Constructor for {@link CassandraUnauthorizedException}. diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/CassandraUncategorizedException.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/CassandraUncategorizedException.java index f65b6daa9..54d396da1 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/CassandraUncategorizedException.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/CassandraUncategorizedException.java @@ -27,7 +27,7 @@ import org.springframework.dao.UncategorizedDataAccessException; */ public class CassandraUncategorizedException extends UncategorizedDataAccessException { - @Serial private static final long serialVersionUID = 1029525121238025444L; + private static final @Serial long serialVersionUID = 1029525121238025444L; /** * Constructor for {@link CassandraUncategorizedException}. diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/CassandraWriteTimeoutException.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/CassandraWriteTimeoutException.java index 6b14ef788..ee213730b 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/CassandraWriteTimeoutException.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/CassandraWriteTimeoutException.java @@ -17,8 +17,8 @@ package org.springframework.data.cassandra; import java.io.Serial; +import org.jspecify.annotations.Nullable; import org.springframework.dao.QueryTimeoutException; -import org.springframework.lang.Nullable; /** * Spring data access exception for a Cassandra write timeout. @@ -28,7 +28,7 @@ import org.springframework.lang.Nullable; */ public class CassandraWriteTimeoutException extends QueryTimeoutException { - @Serial private static final long serialVersionUID = -4374826375213670718L; + private static final @Serial long serialVersionUID = -4374826375213670718L; private @Nullable String writeType; @@ -45,8 +45,7 @@ public class CassandraWriteTimeoutException extends QueryTimeoutException { this.writeType = writeType; } - @Nullable - public String getWriteType() { + public @Nullable String getWriteType() { return writeType; } } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/aot/CassandraManagedTypesBeanRegistrationAotProcessor.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/aot/CassandraManagedTypesBeanRegistrationAotProcessor.java index 3f5c0864c..3302a6bbf 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/aot/CassandraManagedTypesBeanRegistrationAotProcessor.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/aot/CassandraManagedTypesBeanRegistrationAotProcessor.java @@ -15,9 +15,9 @@ */ package org.springframework.data.cassandra.aot; +import org.jspecify.annotations.Nullable; import org.springframework.data.aot.ManagedTypesBeanRegistrationAotProcessor; import org.springframework.data.cassandra.CassandraManagedTypes; -import org.springframework.lang.Nullable; import org.springframework.util.ClassUtils; /** diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/aot/CassandraRuntimeHints.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/aot/CassandraRuntimeHints.java index 3c38ba88c..167765d5a 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/aot/CassandraRuntimeHints.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/aot/CassandraRuntimeHints.java @@ -18,6 +18,7 @@ package org.springframework.data.cassandra.aot; import java.util.Arrays; import java.util.List; +import org.jspecify.annotations.Nullable; import org.springframework.aop.SpringProxy; import org.springframework.aop.framework.Advised; import org.springframework.aot.hint.MemberCategory; @@ -32,7 +33,6 @@ import org.springframework.data.cassandra.observability.CassandraObservationSupp import org.springframework.data.cassandra.repository.support.SimpleCassandraRepository; import org.springframework.data.cassandra.repository.support.SimpleReactiveCassandraRepository; import org.springframework.data.util.ReactiveWrappers; -import org.springframework.lang.Nullable; import org.springframework.util.ClassUtils; import com.datastax.oss.driver.api.core.CqlSession; @@ -106,4 +106,5 @@ class CassandraRuntimeHints implements RuntimeHintsRegistrar { } } } + } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/aot/package-info.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/aot/package-info.java index 735b709bb..603a58125 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/aot/package-info.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/aot/package-info.java @@ -1,7 +1,5 @@ /** * Ahead of Time processing utilities for Spring Data Cassandra. */ -@NonNullApi +@org.jspecify.annotations.NullMarked package org.springframework.data.cassandra.aot; - -import org.springframework.lang.NonNullApi; diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/AbstractCassandraConfiguration.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/AbstractCassandraConfiguration.java index df809a541..59541e322 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/AbstractCassandraConfiguration.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/AbstractCassandraConfiguration.java @@ -19,6 +19,7 @@ import java.util.Arrays; import java.util.Optional; import java.util.Set; +import org.jspecify.annotations.Nullable; import org.springframework.beans.factory.BeanClassLoaderAware; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -38,7 +39,6 @@ import org.springframework.data.cassandra.core.mapping.Table; import org.springframework.data.cassandra.core.mapping.UserTypeResolver; import org.springframework.data.convert.CustomConversions; import org.springframework.data.mapping.context.MappingContext; -import org.springframework.lang.Nullable; import com.datastax.oss.driver.api.core.CqlIdentifier; import com.datastax.oss.driver.api.core.CqlSession; @@ -255,8 +255,7 @@ public abstract class AbstractCassandraConfiguration extends AbstractSessionConf * @return the {@link KeyspacePopulator} or {@code null} if none configured. * @see org.springframework.data.cassandra.core.cql.session.init.ResourceKeyspacePopulator */ - @Nullable - protected KeyspacePopulator keyspaceCleaner() { + protected @Nullable KeyspacePopulator keyspaceCleaner() { return null; } @@ -266,8 +265,7 @@ public abstract class AbstractCassandraConfiguration extends AbstractSessionConf * @return the {@link KeyspacePopulator} or {@code null} if none configured. * @see org.springframework.data.cassandra.core.cql.session.init.ResourceKeyspacePopulator */ - @Nullable - protected KeyspacePopulator keyspacePopulator() { + protected @Nullable KeyspacePopulator keyspacePopulator() { return null; } @@ -293,4 +291,5 @@ public abstract class AbstractCassandraConfiguration extends AbstractSessionConf protected UserTypeResolver userTypeResolver(CqlSession cqlSession) { return new SimpleUserTypeResolver(cqlSession, CqlIdentifier.fromCql(getKeyspaceName())); } + } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/AbstractReactiveCassandraConfiguration.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/AbstractReactiveCassandraConfiguration.java index a391d96a8..b6fe188e4 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/AbstractReactiveCassandraConfiguration.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/AbstractReactiveCassandraConfiguration.java @@ -15,6 +15,7 @@ */ package org.springframework.data.cassandra.config; +import org.jspecify.annotations.Nullable; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactory; import org.springframework.context.annotation.Bean; @@ -27,7 +28,6 @@ import org.springframework.data.cassandra.core.cql.ReactiveCqlOperations; import org.springframework.data.cassandra.core.cql.ReactiveCqlTemplate; import org.springframework.data.cassandra.core.cql.session.DefaultBridgedReactiveSession; import org.springframework.data.cassandra.core.cql.session.DefaultReactiveSessionFactory; -import org.springframework.lang.Nullable; /** * Extension to {@link AbstractCassandraConfiguration} providing Spring Data Cassandra configuration for Spring Data's @@ -63,7 +63,7 @@ public abstract class AbstractReactiveCassandraConfiguration extends AbstractCas */ @Bean public ReactiveSessionFactory reactiveCassandraSessionFactory() { - return new DefaultReactiveSessionFactory(beanFactory.getBean(ReactiveSession.class)); + return new DefaultReactiveSessionFactory(getBean(ReactiveSession.class)); } /** @@ -75,8 +75,7 @@ public abstract class AbstractReactiveCassandraConfiguration extends AbstractCas */ @Bean public ReactiveCassandraTemplate reactiveCassandraTemplate() { - return new ReactiveCassandraTemplate(beanFactory.getBean(ReactiveSessionFactory.class), - beanFactory.getBean(CassandraConverter.class)); + return new ReactiveCassandraTemplate(getBean(ReactiveSessionFactory.class), getBean(CassandraConverter.class)); } /** @@ -87,7 +86,7 @@ public abstract class AbstractReactiveCassandraConfiguration extends AbstractCas */ @Bean public ReactiveCqlTemplate reactiveCqlTemplate() { - return new ReactiveCqlTemplate(beanFactory.getBean(ReactiveSessionFactory.class)); + return new ReactiveCqlTemplate(getBean(ReactiveSessionFactory.class)); } @Override @@ -95,4 +94,14 @@ public abstract class AbstractReactiveCassandraConfiguration extends AbstractCas this.beanFactory = beanFactory; super.setBeanFactory(beanFactory); } + + private T getBean(Class requiredType) { + + if (beanFactory == null) { + throw new IllegalStateException("BeanFactory must not be null"); + } + + return beanFactory.getBean(requiredType); + } + } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/AbstractSessionConfiguration.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/AbstractSessionConfiguration.java index 91f6a7000..23266c6b2 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/AbstractSessionConfiguration.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/AbstractSessionConfiguration.java @@ -22,6 +22,8 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import org.jspecify.annotations.Nullable; + import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; @@ -34,8 +36,6 @@ import org.springframework.data.cassandra.core.cql.CqlTemplate; import org.springframework.data.cassandra.core.cql.keyspace.CreateKeyspaceSpecification; import org.springframework.data.cassandra.core.cql.keyspace.DropKeyspaceSpecification; import org.springframework.data.cassandra.core.cql.session.DefaultSessionFactory; -import org.springframework.lang.NonNull; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.StringUtils; @@ -99,7 +99,7 @@ public abstract class AbstractSessionConfiguration implements BeanFactoryAware { * @see org.springframework.beans.factory.BeanFactory#getBean(Class) * @see #getBeanFactory() */ - protected T requireBeanOfType(@NonNull Class beanType) { + protected T requireBeanOfType(Class beanType) { return getBeanFactory().getBean(beanType); } @@ -110,9 +110,8 @@ public abstract class AbstractSessionConfiguration implements BeanFactoryAware { * @deprecated since 3.0, use {@link #getSessionName()} instead. * @since 1.5 */ - @Nullable @Deprecated - protected String getClusterName() { + protected @Nullable String getClusterName() { return null; } @@ -130,8 +129,7 @@ public abstract class AbstractSessionConfiguration implements BeanFactoryAware { * * @return the local data center name. Can be {@literal null} when using an Astra connection bundle. */ - @Nullable - protected String getLocalDataCenter() { + protected @Nullable String getLocalDataCenter() { return "datacenter1"; } @@ -141,8 +139,7 @@ public abstract class AbstractSessionConfiguration implements BeanFactoryAware { * @return the session name; may be {@literal null}. * @since 3.0 */ - @Nullable - protected String getSessionName() { + protected @Nullable String getSessionName() { return null; } @@ -151,8 +148,7 @@ public abstract class AbstractSessionConfiguration implements BeanFactoryAware { * * @return the {@link CompressionType}, may be {@literal null}. */ - @Nullable - protected CompressionType getCompressionType() { + protected @Nullable CompressionType getCompressionType() { return null; } @@ -236,8 +232,7 @@ public abstract class AbstractSessionConfiguration implements BeanFactoryAware { * @return the {@link DriverConfigLoaderBuilderConfigurer}; may be {@literal null}. * @since 3.1.2 */ - @Nullable - protected DriverConfigLoaderBuilderConfigurer getDriverConfigLoaderBuilderConfigurer() { + protected @Nullable DriverConfigLoaderBuilderConfigurer getDriverConfigLoaderBuilderConfigurer() { return null; } @@ -250,8 +245,7 @@ public abstract class AbstractSessionConfiguration implements BeanFactoryAware { * @see Driver * Configuration */ - @Nullable - protected Resource getDriverConfigurationResource() { + protected @Nullable Resource getDriverConfigurationResource() { return null; } @@ -395,4 +389,5 @@ public abstract class AbstractSessionConfiguration implements BeanFactoryAware { } } + } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/BeanDefinitionUtils.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/BeanDefinitionUtils.java deleted file mode 100644 index 8ac46ce1a..000000000 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/BeanDefinitionUtils.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2013-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.cassandra.config; - -import org.springframework.beans.factory.BeanFactory; -import org.springframework.beans.factory.BeanFactoryUtils; -import org.springframework.beans.factory.FactoryBean; -import org.springframework.beans.factory.ListableBeanFactory; -import org.springframework.beans.factory.NoSuchBeanDefinitionException; -import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.beans.factory.config.BeanDefinitionHolder; -import org.springframework.beans.factory.support.BeanDefinitionRegistry; - -/** - * Utilities to lookup {@link BeanDefinition bean definitions} for a {@link ListableBeanFactory} and to conditionally - * register {@link BeanDefinition bean definitions}. - * - * @author Matthew Adams - * @author Mark Paluch - */ -class BeanDefinitionUtils { - - /** - * Returns all {@link BeanDefinitionHolder}s with the given type. - * - * @param registry The {@link BeanDefinitionRegistry}, often the very same instance as the {@code factor} parameter. - * @param factory The {@link ListableBeanFactory}, often the very same instance as the {@code registry} parameter. - * @param type The required {@link BeanDefinition}'s type. - * @param includeNonSingletons Whether to include beans with scope other than {@code singleton} - * @param allowEagerInit Whether to allow eager initialization of beans. - * @return The {@link BeanDefinitionHolder}s -- never returns null. - * @see BeanFactoryUtils#beanNamesForTypeIncludingAncestors(ListableBeanFactory, Class, boolean, boolean) - */ - static BeanDefinitionHolder[] getBeanDefinitionsOfType(BeanDefinitionRegistry registry, ListableBeanFactory factory, - Class type, boolean includeNonSingletons, boolean allowEagerInit) { - - String[] names = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(factory, type, includeNonSingletons, - allowEagerInit); - - if (names.length == 0) { - return new BeanDefinitionHolder[] {}; - } - - BeanDefinitionHolder[] array = new BeanDefinitionHolder[names.length]; - - for (int i = 0; i < names.length; i++) { - - String name = names[i]; - BeanDefinition beanDefinition = null; - - while (beanDefinition == null) { - try { - beanDefinition = registry.getBeanDefinition(name); - } catch (NoSuchBeanDefinitionException x) { - if (FactoryBean.class.isAssignableFrom(type)) { // try unmanged BeanFactory-prefixed name - name = name.substring(BeanFactory.FACTORY_BEAN_PREFIX.length()); - } else { - throw x; - } - } - } - - array[i] = new BeanDefinitionHolder(beanDefinition, name); - } - - return array; - } -} diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/CassandraAuditingBeanDefinitionParser.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/CassandraAuditingBeanDefinitionParser.java index 0bc42ef92..00360fe2b 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/CassandraAuditingBeanDefinitionParser.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/CassandraAuditingBeanDefinitionParser.java @@ -17,6 +17,7 @@ package org.springframework.data.cassandra.config; import static org.springframework.data.config.ParsingUtils.*; +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; @@ -28,7 +29,6 @@ import org.springframework.data.auditing.config.IsNewAwareAuditingHandlerBeanDef import org.springframework.data.cassandra.core.mapping.CassandraMappingContext; import org.springframework.data.cassandra.core.mapping.event.AuditingEntityCallback; import org.springframework.data.cassandra.core.mapping.event.ReactiveAuditingEntityCallback; -import org.springframework.lang.Nullable; import org.springframework.util.ClassUtils; import org.springframework.util.StringUtils; import org.w3c.dom.Element; @@ -42,7 +42,7 @@ import org.w3c.dom.Element; */ public class CassandraAuditingBeanDefinitionParser extends AbstractSingleBeanDefinitionParser { - private static boolean PROJECT_REACTOR_AVAILABLE = ClassUtils.isPresent("reactor.core.publisher.Mono", + private static final boolean PROJECT_REACTOR_AVAILABLE = ClassUtils.isPresent("reactor.core.publisher.Mono", CassandraAuditingRegistrar.class.getClassLoader()); @Override @@ -56,6 +56,7 @@ public class CassandraAuditingBeanDefinitionParser extends AbstractSingleBeanDef } @Override + @SuppressWarnings("NullAway") protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) { String mappingContextRef = element.getAttribute("mapping-context-ref"); @@ -96,4 +97,5 @@ public class CassandraAuditingBeanDefinitionParser extends AbstractSingleBeanDef registry.registerBeanDefinition(ReactiveAuditingEntityCallback.class.getName(), builder.getBeanDefinition()); } + } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/CassandraAuditingRegistrar.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/CassandraAuditingRegistrar.java index abffb0025..fab24547f 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/CassandraAuditingRegistrar.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/CassandraAuditingRegistrar.java @@ -78,4 +78,5 @@ class CassandraAuditingRegistrar extends AuditingBeanDefinitionRegistrarSupport registerInfrastructureBeanWithId(listenerBeanDefinitionBuilder.getBeanDefinition(), AuditingEntityCallback.class.getName(), registry); } + } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/CassandraCqlTemplateFactoryBean.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/CassandraCqlTemplateFactoryBean.java index 086779fe4..6f64dde78 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/CassandraCqlTemplateFactoryBean.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/CassandraCqlTemplateFactoryBean.java @@ -15,12 +15,12 @@ */ package org.springframework.data.cassandra.config; +import org.jspecify.annotations.Nullable; import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.InitializingBean; import org.springframework.data.cassandra.SessionFactory; import org.springframework.data.cassandra.core.cql.CqlTemplate; import org.springframework.data.cassandra.core.cql.session.DefaultSessionFactory; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import com.datastax.oss.driver.api.core.CqlSession; @@ -39,6 +39,9 @@ public class CassandraCqlTemplateFactoryBean implements FactoryBean @Override public CqlTemplate getObject() { + + Assert.state(this.template != null, "CqlTemplate has not been initialized"); + return template; } @@ -89,4 +92,5 @@ public class CassandraCqlTemplateFactoryBean implements FactoryBean this.sessionFactory = sessionFactory; } + } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/CassandraCqlTemplateParser.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/CassandraCqlTemplateParser.java index 037e9ee7e..1917265ae 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/CassandraCqlTemplateParser.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/CassandraCqlTemplateParser.java @@ -58,4 +58,5 @@ class CassandraCqlTemplateParser extends AbstractSingleBeanDefinitionParser { builder.getRawBeanDefinition().setSource(element); } + } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/CassandraEntityClassScanner.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/CassandraEntityClassScanner.java index e1346c36a..9ebd5cf72 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/CassandraEntityClassScanner.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/CassandraEntityClassScanner.java @@ -23,10 +23,10 @@ import java.util.HashSet; import java.util.Set; import java.util.stream.Collectors; +import org.jspecify.annotations.Nullable; import org.springframework.data.cassandra.core.mapping.PrimaryKeyClass; import org.springframework.data.cassandra.core.mapping.Table; import org.springframework.data.util.TypeScanner; -import org.springframework.lang.Nullable; import org.springframework.util.ClassUtils; import org.springframework.util.ObjectUtils; @@ -199,7 +199,8 @@ public class CassandraEntityClassScanner { if (this.beanClassLoader != null) { scanner = TypeScanner.typeScanner(this.beanClassLoader); } else { - scanner = TypeScanner.typeScanner(ClassUtils.getDefaultClassLoader()); + ClassLoader cl = ClassUtils.getDefaultClassLoader(); + scanner = TypeScanner.typeScanner(cl != null ? cl : getClass().getClassLoader()); } return scanner.forTypesAnnotatedWith(getEntityAnnotations()).scanPackages(getEntityBasePackages()).collectAsSet(); @@ -214,4 +215,5 @@ public class CassandraEntityClassScanner { protected Class[] getEntityAnnotations() { return new Class[] { Table.class, PrimaryKeyClass.class }; } + } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/CassandraMappingContextParser.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/CassandraMappingContextParser.java index b0abd1c7e..2e1e696e4 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/CassandraMappingContextParser.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/CassandraMappingContextParser.java @@ -21,6 +21,8 @@ import java.util.List; import java.util.Map; import java.util.Set; +import org.jspecify.annotations.Nullable; + import org.springframework.beans.factory.BeanDefinitionStoreException; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.support.AbstractBeanDefinition; @@ -35,6 +37,7 @@ import org.springframework.data.cassandra.core.mapping.SimpleUserTypeResolver; import org.springframework.util.Assert; import org.springframework.util.StringUtils; import org.springframework.util.xml.DomUtils; + import org.w3c.dom.Element; /** @@ -65,7 +68,7 @@ class CassandraMappingContextParser extends AbstractSingleBeanDefinitionParser { builder.getRawBeanDefinition().setSource(element); } - private void parseMapping(Element element, BeanDefinitionBuilder builder, ClassLoader classLoader) { + private void parseMapping(Element element, BeanDefinitionBuilder builder, @Nullable ClassLoader classLoader) { String packages = element.getAttribute("entity-base-packages"); @@ -186,4 +189,5 @@ class CassandraMappingContextParser extends AbstractSingleBeanDefinitionParser { return propertyMappings; } + } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/CassandraMappingConverterParser.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/CassandraMappingConverterParser.java index bd707f98d..4b37037bc 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/CassandraMappingConverterParser.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/CassandraMappingConverterParser.java @@ -56,4 +56,5 @@ class CassandraMappingConverterParser extends AbstractSingleBeanDefinitionParser builder.addConstructorArgReference(mappingRef); builder.getRawBeanDefinition().setSource(element); } + } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/CassandraNamespaceHandler.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/CassandraNamespaceHandler.java index 61d38b511..d45897f3b 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/CassandraNamespaceHandler.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/CassandraNamespaceHandler.java @@ -39,4 +39,5 @@ public class CassandraNamespaceHandler extends NamespaceHandlerSupport { registerBeanDefinitionParser("mapping", new CassandraMappingContextParser()); registerBeanDefinitionParser("initialize-keyspace", new InitializeKeyspaceBeanDefinitionParser()); } + } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/CassandraTemplateFactoryBean.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/CassandraTemplateFactoryBean.java index e8b8c421f..18f790fa1 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/CassandraTemplateFactoryBean.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/CassandraTemplateFactoryBean.java @@ -15,6 +15,7 @@ */ package org.springframework.data.cassandra.config; +import org.jspecify.annotations.Nullable; import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.InitializingBean; import org.springframework.data.cassandra.SessionFactory; @@ -23,7 +24,6 @@ import org.springframework.data.cassandra.core.convert.CassandraConverter; import org.springframework.data.cassandra.core.convert.MappingCassandraConverter; import org.springframework.data.cassandra.core.cql.CqlOperations; import org.springframework.data.cassandra.core.cql.session.DefaultSessionFactory; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import com.datastax.oss.driver.api.core.CqlSession; @@ -57,10 +57,14 @@ public class CassandraTemplateFactoryBean implements FactoryBean { - executeSpecificationsAndScripts(this.keyspaceDrops, this.keyspaceShutdownScripts, this.systemSession); + if (this.systemSession != null) { + executeSpecificationsAndScripts(this.keyspaceDrops, this.keyspaceShutdownScripts, this.systemSession); + } }; if (this.suspendLifecycleSchemaRefresh) { SchemaUtils.withSuspendedAsyncSchemaRefresh(this.session, schemaActionRunnable); + + if (this.systemSession != null) { SchemaUtils.withSuspendedAsyncSchemaRefresh(this.systemSession, systemSchemaActionRunnable); + } } else { schemaActionRunnable.run(); systemSchemaActionRunnable.run(); @@ -709,14 +715,18 @@ public class CqlSessionFactoryBean * Close the regular session object. */ protected void closeSession() { - this.session.close(); + if (this.session != null) { + this.session.close(); + } } /** * Close the system session object. */ protected void closeSystemSession() { - this.systemSession.close(); + if (this.systemSession != null) { + this.systemSession.close(); + } } /** @@ -860,5 +870,7 @@ public class CqlSessionFactoryBean public int getPort() { return port; } + } + } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/DefaultBeanNames.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/DefaultBeanNames.java index dd63468f5..bfbf74364 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/DefaultBeanNames.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/DefaultBeanNames.java @@ -25,4 +25,5 @@ public interface DefaultBeanNames extends DefaultCqlBeanNames { String CONVERTER = "cassandraConverter"; String CONTEXT = "cassandraMappingContext"; String USER_TYPE_RESOLVER = "userTypeResolver"; + } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/DefaultCqlBeanNames.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/DefaultCqlBeanNames.java index b58542073..e4c83f884 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/DefaultCqlBeanNames.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/DefaultCqlBeanNames.java @@ -30,4 +30,5 @@ public interface DefaultCqlBeanNames { String SESSION = "cassandraSession"; String SESSION_FACTORY = "cassandraSessionFactory"; String TEMPLATE = "cqlTemplate"; + } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/EnableCassandraAuditing.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/EnableCassandraAuditing.java index 55bf19ceb..a1047e87c 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/EnableCassandraAuditing.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/EnableCassandraAuditing.java @@ -67,4 +67,5 @@ public @interface EnableCassandraAuditing { * @return */ String dateTimeProviderRef() default ""; + } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/EnableReactiveCassandraAuditing.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/EnableReactiveCassandraAuditing.java index 2711b117d..ca1fa9080 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/EnableReactiveCassandraAuditing.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/EnableReactiveCassandraAuditing.java @@ -67,4 +67,5 @@ public @interface EnableReactiveCassandraAuditing { * @return */ String dateTimeProviderRef() default ""; + } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/InitializeKeyspaceBeanDefinitionParser.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/InitializeKeyspaceBeanDefinitionParser.java index 0a829d59d..65fe18d90 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/InitializeKeyspaceBeanDefinitionParser.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/InitializeKeyspaceBeanDefinitionParser.java @@ -19,6 +19,7 @@ import static org.springframework.data.cassandra.config.ParsingUtils.*; import java.util.List; +import org.jspecify.annotations.Nullable; import org.springframework.beans.BeanMetadataElement; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.TypedStringValue; @@ -30,7 +31,6 @@ import org.springframework.beans.factory.xml.ParserContext; import org.springframework.data.cassandra.core.cql.session.init.CompositeKeyspacePopulator; import org.springframework.data.cassandra.core.cql.session.init.ResourceKeyspacePopulator; import org.springframework.data.cassandra.core.cql.session.init.SessionFactoryInitializer; -import org.springframework.lang.Nullable; import org.springframework.util.StringUtils; import org.springframework.util.xml.DomUtils; import org.w3c.dom.Element; @@ -137,4 +137,5 @@ class InitializeKeyspaceBeanDefinitionParser extends AbstractBeanDefinitionParse return null; } + } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/KeyspaceActionSpecificationFactory.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/KeyspaceActionSpecificationFactory.java index e918d6936..25918ab46 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/KeyspaceActionSpecificationFactory.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/KeyspaceActionSpecificationFactory.java @@ -260,5 +260,7 @@ class KeyspaceActionSpecificationFactory { return new KeyspaceActionSpecificationFactory(name, new ArrayList<>(replications), replicationStrategy, replicationFactor, durableWrites); } + } + } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/KeyspaceActionSpecificationFactoryBean.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/KeyspaceActionSpecificationFactoryBean.java index bb1e14edd..dba9cb7ba 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/KeyspaceActionSpecificationFactoryBean.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/KeyspaceActionSpecificationFactoryBean.java @@ -19,13 +19,13 @@ import java.util.LinkedList; import java.util.List; import java.util.Set; +import org.jspecify.annotations.Nullable; import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.InitializingBean; import org.springframework.data.cassandra.config.KeyspaceActionSpecificationFactory.KeyspaceActionSpecificationFactoryBuilder; import org.springframework.data.cassandra.core.cql.keyspace.DataCenterReplication; import org.springframework.data.cassandra.core.cql.keyspace.KeyspaceActionSpecification; import org.springframework.data.cassandra.core.cql.keyspace.KeyspaceOption.ReplicationStrategy; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -101,7 +101,7 @@ public class KeyspaceActionSpecificationFactoryBean implements FactoryBean getObjectType() { return PersistentEntities.class; } + } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/SchemaAction.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/SchemaAction.java index f86bf5388..e923f5bb9 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/SchemaAction.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/SchemaAction.java @@ -48,4 +48,5 @@ public enum SchemaAction { * Drop all tables in the keyspace, then create each table as necessary. */ RECREATE_DROP_UNUSED + } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/SchemaUtils.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/SchemaUtils.java index 1cccbaf9c..22e382d7a 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/SchemaUtils.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/SchemaUtils.java @@ -101,4 +101,5 @@ class SchemaUtils { return CompletableFuture.completedFuture(null); } + } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/SessionFactoryBeanDefinitionParser.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/SessionFactoryBeanDefinitionParser.java index 9589e9ea9..4c855b869 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/SessionFactoryBeanDefinitionParser.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/SessionFactoryBeanDefinitionParser.java @@ -56,4 +56,5 @@ class SessionFactoryBeanDefinitionParser extends AbstractSingleBeanDefinitionPar InitializeKeyspaceBeanDefinitionParser.parseKeyspacePopulator(element, builder); builder.getRawBeanDefinition().setSource(element); } + } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/SessionFactoryFactoryBean.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/SessionFactoryFactoryBean.java index 660ce1d77..aa56c046c 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/SessionFactoryFactoryBean.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/SessionFactoryFactoryBean.java @@ -15,6 +15,7 @@ */ package org.springframework.data.cassandra.config; +import org.jspecify.annotations.Nullable; import org.springframework.beans.factory.config.AbstractFactoryBean; import org.springframework.data.cassandra.SessionFactory; import org.springframework.data.cassandra.core.CassandraAdminOperations; @@ -26,7 +27,6 @@ import org.springframework.data.cassandra.core.cql.session.DefaultSessionFactory import org.springframework.data.cassandra.core.cql.session.init.KeyspacePopulator; import org.springframework.data.cassandra.core.cql.session.init.SessionFactoryInitializer; import org.springframework.data.cassandra.core.mapping.CassandraMappingContext; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import com.datastax.oss.driver.api.core.CqlSession; @@ -47,9 +47,9 @@ public class SessionFactoryFactoryBean extends AbstractFactoryBean getObjectType() { + public @Nullable Class getObjectType() { return SessionFactory.class; } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/package-info.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/package-info.java index 0619da9a4..a481231a5 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/package-info.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/package-info.java @@ -1,7 +1,7 @@ /** * Spring Data Cassandra {@link org.springframework.beans.factory.FactoryBean factory beans} and configuration. */ -@NonNullApi +@org.jspecify.annotations.NullMarked package org.springframework.data.cassandra.config; -import org.springframework.lang.NonNullApi; + diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/AsyncCassandraOperations.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/AsyncCassandraOperations.java index 35b18799e..febc49b4f 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/AsyncCassandraOperations.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/AsyncCassandraOperations.java @@ -19,6 +19,8 @@ import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.function.Consumer; +import org.jspecify.annotations.Nullable; + import org.springframework.dao.DataAccessException; import org.springframework.data.cassandra.core.convert.CassandraConverter; import org.springframework.data.cassandra.core.cql.AsyncCqlOperations; @@ -97,7 +99,7 @@ public interface AsyncCassandraOperations { * @return the converted object or {@literal null}. * @throws DataAccessException if there is any problem executing the query. */ - CompletableFuture selectOne(String cql, Class entityClass) throws DataAccessException; + CompletableFuture<@Nullable T> selectOne(String cql, Class entityClass) throws DataAccessException; // ------------------------------------------------------------------------- // Methods dealing with com.datastax.oss.driver.api.core.cql.Statement @@ -157,7 +159,7 @@ public interface AsyncCassandraOperations { * @return the converted object or {@literal null}. * @throws DataAccessException if there is any problem executing the query. */ - CompletableFuture selectOne(Statement statement, Class entityClass) throws DataAccessException; + CompletableFuture<@Nullable T> selectOne(Statement statement, Class entityClass) throws DataAccessException; // ------------------------------------------------------------------------- // Methods dealing with org.springframework.data.cassandra.core.query.Query @@ -205,7 +207,7 @@ public interface AsyncCassandraOperations { * @return the converted object or {@literal null}. * @throws DataAccessException if there is any problem executing the query. */ - CompletableFuture selectOne(Query query, Class entityClass) throws DataAccessException; + CompletableFuture<@Nullable T> selectOne(Query query, Class entityClass) throws DataAccessException; /** * Update the queried entities and return {@literal true} if the update was applied. @@ -286,7 +288,7 @@ public interface AsyncCassandraOperations { * @return the converted object or {@literal null}. * @throws DataAccessException if there is any problem executing the query. */ - CompletableFuture selectOneById(Object id, Class entityClass) throws DataAccessException; + CompletableFuture<@Nullable T> selectOneById(Object id, Class entityClass) throws DataAccessException; /** * Insert the given entity and return the entity if the insert was applied. @@ -295,7 +297,7 @@ public interface AsyncCassandraOperations { * @return the inserted entity. * @throws DataAccessException if there is any problem executing the query. */ - CompletableFuture insert(T entity) throws DataAccessException; + CompletableFuture<@Nullable T> insert(T entity) throws DataAccessException; /** * Insert the given entity applying {@link WriteOptions} and return the entity if the insert was applied. diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/AsyncCassandraTemplate.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/AsyncCassandraTemplate.java index 0050c318c..0d622aedf 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/AsyncCassandraTemplate.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/AsyncCassandraTemplate.java @@ -27,7 +27,7 @@ import java.util.stream.StreamSupport; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; - +import org.jspecify.annotations.Nullable; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; @@ -61,7 +61,6 @@ import org.springframework.data.projection.EntityProjection; import org.springframework.data.projection.ProjectionFactory; import org.springframework.data.projection.SpelAwareProxyProjectionFactory; import org.springframework.data.util.Streamable; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import com.datastax.oss.driver.api.core.CqlIdentifier; @@ -500,11 +499,11 @@ public class AsyncCassandraTemplate SimpleStatement statement = countStatement.build(); - CompletableFuture result = doExecute(statement, it -> { + CompletableFuture<@Nullable Long> result = doExecute(statement, it -> { - SingleColumnRowMapper mapper = SingleColumnRowMapper.newInstance(Long.class); + SingleColumnRowMapper<@Nullable Long> mapper = SingleColumnRowMapper.newInstance(Long.class); - Row row = DataAccessUtils.nullableSingleResult(Streamable.of(it.currentPage()).toList()); + Row row = DataAccessUtils.requiredUniqueResult(Streamable.of(it.currentPage()).toList()); return mapper.mapRow(row, 0); }); @@ -827,7 +826,8 @@ public class AsyncCassandraTemplate return doExecute(statement, Function.identity()); } - private CompletableFuture doExecute(Statement statement, Function mappingFunction) { + private CompletableFuture doExecute(Statement statement, + Function mappingFunction) { if (PreparedStatementDelegate.canPrepare(isUsePreparedStatements(), statement, log)) { @@ -861,6 +861,7 @@ public class AsyncCassandraTemplate return accessor.getPageSize(); } } + class GetConfiguredPageSize implements AsyncSessionCallback, CqlProvider { @Override public CompletableFuture doInSession(CqlSession session) { @@ -876,7 +877,6 @@ public class AsyncCassandraTemplate return getAsyncCqlOperations().execute(new GetConfiguredPageSize()).join(); } - @SuppressWarnings("unchecked") private Function getMapper(Class entityType, Class targetType, CqlIdentifier tableName) { EntityProjection projection = entityOperations.introspectProjection(targetType, entityType); diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraAdminTemplate.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraAdminTemplate.java index 9ea3e3a57..31e72bf1f 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraAdminTemplate.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraAdminTemplate.java @@ -161,7 +161,6 @@ public class CassandraAdminTemplate extends CassandraTemplate implements Cassand Assert.notNull(keyspace, "Keyspace name must not be null"); Assert.notNull(tableName, "Table name must not be null"); - // noinspection ConstantConditions return getCqlOperations().execute((SessionCallback>) session -> { return session.getMetadata().getKeyspace(keyspace).flatMap(it -> it.getTable(tableName)); }); @@ -170,7 +169,6 @@ public class CassandraAdminTemplate extends CassandraTemplate implements Cassand @Override public KeyspaceMetadata getKeyspaceMetadata() { - // noinspection ConstantConditions return getCqlOperations().execute((SessionCallback) session -> { return session.getKeyspace().flatMap(it -> session.getMetadata().getKeyspace(it)).orElseThrow(() -> { diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraOperations.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraOperations.java index c18006aa0..943473ee2 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraOperations.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraOperations.java @@ -19,6 +19,7 @@ import java.util.Iterator; import java.util.List; import java.util.stream.Stream; +import org.jspecify.annotations.Nullable; import org.springframework.dao.DataAccessException; import org.springframework.data.cassandra.core.convert.CassandraConverter; import org.springframework.data.cassandra.core.cql.CqlOperations; @@ -28,7 +29,6 @@ import org.springframework.data.cassandra.core.query.CassandraPageRequest; import org.springframework.data.cassandra.core.query.Query; import org.springframework.data.cassandra.core.query.Update; import org.springframework.data.domain.Slice; -import org.springframework.lang.Nullable; import com.datastax.oss.driver.api.core.CqlIdentifier; import com.datastax.oss.driver.api.core.cql.BatchType; @@ -133,8 +133,7 @@ public interface CassandraOperations extends FluentCassandraOperations { * @return the converted object or {@literal null}. * @throws DataAccessException if there is any problem executing the query. */ - @Nullable - T selectOne(String cql, Class entityClass) throws DataAccessException; + @Nullable T selectOne(String cql, Class entityClass) throws DataAccessException; // ------------------------------------------------------------------------- // Methods dealing with com.datastax.oss.driver.api.core.cql.Statement @@ -195,8 +194,7 @@ public interface CassandraOperations extends FluentCassandraOperations { * @return the converted object or {@literal null}. * @throws DataAccessException if there is any problem executing the query. */ - @Nullable - T selectOne(Statement statement, Class entityClass) throws DataAccessException; + @Nullable T selectOne(Statement statement, Class entityClass) throws DataAccessException; // ------------------------------------------------------------------------- // Methods dealing with org.springframework.data.cassandra.core.query.Query @@ -248,8 +246,7 @@ public interface CassandraOperations extends FluentCassandraOperations { * @throws DataAccessException if there is any problem executing the query. * @since 2.0 */ - @Nullable - T selectOne(Query query, Class entityClass) throws DataAccessException; + @Nullable T selectOne(Query query, Class entityClass) throws DataAccessException; /** * Update the queried entities and return {@literal true} if the update was applied. @@ -329,8 +326,7 @@ public interface CassandraOperations extends FluentCassandraOperations { * @return the converted object or {@literal null}. * @throws DataAccessException if there is any problem executing the query. */ - @Nullable - T selectOneById(Object id, Class entityClass) throws DataAccessException; + @Nullable T selectOneById(Object id, Class entityClass) throws DataAccessException; /** * Insert the given entity and return the entity if the insert was applied. diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraPersistentEntitySchemaCreator.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraPersistentEntitySchemaCreator.java index d6c60d69d..ff6718ac5 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraPersistentEntitySchemaCreator.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraPersistentEntitySchemaCreator.java @@ -159,6 +159,7 @@ public class CassandraPersistentEntitySchemaCreator { * @param ifNotExists {@literal true} to create types using {@code IF NOT EXISTS}. * @return {@link List} of {@link CreateUserTypeSpecification}. */ + @SuppressWarnings("NullAway") protected List createUserTypeSpecifications(boolean ifNotExists) { List> entities = new ArrayList<>( diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraTemplate.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraTemplate.java index 132f55835..9ec3804cb 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraTemplate.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraTemplate.java @@ -23,6 +23,7 @@ import java.util.stream.Stream; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.jspecify.annotations.Nullable; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; @@ -57,7 +58,6 @@ import org.springframework.data.mapping.callback.EntityCallbacks; import org.springframework.data.projection.EntityProjection; import org.springframework.data.projection.ProjectionFactory; import org.springframework.data.projection.SpelAwareProxyProjectionFactory; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import com.datastax.oss.driver.api.core.CqlIdentifier; @@ -318,7 +318,7 @@ public class CassandraTemplate implements CassandraOperations, ApplicationEventP } @Override - public T selectOne(String cql, Class entityClass) { + public @Nullable T selectOne(String cql, Class entityClass) { Assert.hasText(cql, "CQL must not be empty"); Assert.notNull(entityClass, "Entity type must not be null"); @@ -360,7 +360,7 @@ public class CassandraTemplate implements CassandraOperations, ApplicationEventP } @Override - public T selectOne(Statement statement, Class entityClass) { + public @Nullable T selectOne(Statement statement, Class entityClass) { List result = select(statement, entityClass); return result.isEmpty() ? null : result.get(0); @@ -421,7 +421,7 @@ public class CassandraTemplate implements CassandraOperations, ApplicationEventP } @Override - public T selectOne(Query query, Class entityClass) throws DataAccessException { + public @Nullable T selectOne(Query query, Class entityClass) throws DataAccessException { List result = select(query, entityClass); @@ -472,7 +472,6 @@ public class CassandraTemplate implements CassandraOperations, ApplicationEventP return doExecute(updateStatement.build()).wasApplied(); } - @Nullable WriteResult doUpdate(Query query, org.springframework.data.cassandra.core.query.Update update, Class entityClass, CqlIdentifier tableName) { @@ -493,7 +492,6 @@ public class CassandraTemplate implements CassandraOperations, ApplicationEventP return result != null && result.wasApplied(); } - @Nullable WriteResult doDelete(Query query, Class entityClass, CqlIdentifier tableName) { StatementBuilder delete = getStatementFactory().delete(query, getRequiredPersistentEntity(entityClass), @@ -535,7 +533,7 @@ public class CassandraTemplate implements CassandraOperations, ApplicationEventP StatementBuilder