diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/SessionFactory.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/SessionFactory.java index f3b171ddb..8c19c44ef 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/SessionFactory.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/SessionFactory.java @@ -15,21 +15,23 @@ */ package org.springframework.data.cassandra; - import com.datastax.oss.driver.api.core.CqlSession; +import com.datastax.oss.driver.api.core.session.Session; /** - * A factory for Apache Cassandra sessions. - *

+ * A factory for Apache Cassandra {@link Session sessions}. + * * A {@link SessionFactory} object is the preferred means of getting a connection. The {@link SessionFactory} interface * is implemented by a {@link CqlSession} provider. - *

+ * * A {@link SessionFactory} object can have properties that can be modified when necessary. For example, if the * {@link CqlSession} is moved to a different server, the property for the server can be changed. The benefit is that * because the data source's properties can be changed, any code accessing that {@link SessionFactory} does not need to * be changed. * * @author Mark Paluch + * @see com.datastax.oss.driver.api.core.CqlSession + * @see com.datastax.oss.driver.api.core.session.Session * @since 2.0 */ @FunctionalInterface @@ -40,6 +42,7 @@ public interface SessionFactory { * object represents. * * @return a {@link CqlSession} to Apache Cassandra. + * @see com.datastax.oss.driver.api.core.CqlSession */ CqlSession getSession(); 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 e43d6816d..8754a542a 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,10 +19,7 @@ import java.util.Collections; import java.util.Optional; import java.util.Set; -import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanClassLoaderAware; -import org.springframework.beans.factory.BeanFactory; -import org.springframework.beans.factory.BeanFactoryAware; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.convert.converter.Converter; @@ -41,7 +38,6 @@ 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 org.springframework.util.Assert; import com.datastax.oss.driver.api.core.CqlIdentifier; import com.datastax.oss.driver.api.core.CqlSession; @@ -55,23 +51,57 @@ import com.datastax.oss.driver.api.core.CqlSession; * @author Mark Paluch */ @Configuration +@SuppressWarnings("unused") public abstract class AbstractCassandraConfiguration extends AbstractSessionConfiguration - implements BeanClassLoaderAware, BeanFactoryAware { + implements BeanClassLoaderAware { private @Nullable ClassLoader beanClassLoader; - private @Nullable BeanFactory beanFactory; /** - * Returns the initialized {@link CqlSession} instance. + * Creates a {@link CassandraConverter} using the configured {@link #cassandraMapping()}. Will apply all specified + * {@link #customConversions()}. * - * @return the {@link CqlSession}. - * @throws IllegalStateException if the session factory is not initialized. + * @return {@link CassandraConverter} used to convert Java and Cassandra value types during the mapping process. + * @see #cassandraMapping() + * @see #customConversions() */ - protected SessionFactory getRequiredSessionFactory() { + @Bean + public CassandraConverter cassandraConverter() { - Assert.state(beanFactory != null, "BeanFactory not initialized"); + MappingCassandraConverter mappingCassandraConverter = + new MappingCassandraConverter(requireBeanOfType(CassandraMappingContext.class)); - return beanFactory.getBean(SessionFactory.class); + mappingCassandraConverter.setCustomConversions(requireBeanOfType(CassandraCustomConversions.class)); + + return mappingCassandraConverter; + } + + /** + * Return the {@link MappingContext} instance to map Entities to properties. + * + * @throws ClassNotFoundException if the Cassandra Entity class type identified by name cannot be found during the + * scan. + * @see CassandraMappingContext + */ + @Bean + public CassandraMappingContext cassandraMapping() throws ClassNotFoundException { + + UserTypeResolver userTypeResolver = + new SimpleUserTypeResolver(getRequiredSession(), CqlIdentifier.fromCql(getKeyspaceName())); + + CassandraMappingContext mappingContext = + new CassandraMappingContext(userTypeResolver, SimpleTupleTypeFactory.DEFAULT); + + CustomConversions customConversions = requireBeanOfType(CustomConversions.class); + + getBeanClassLoader().ifPresent(mappingContext::setBeanClassLoader); + + mappingContext.setCodecRegistry(getRequiredSession().getContext().getCodecRegistry()); + mappingContext.setCustomConversions(customConversions); + mappingContext.setInitialEntitySet(getInitialEntitySet()); + mappingContext.setSimpleTypeHolder(customConversions.getSimpleTypeHolder()); + + return mappingContext; } /** @@ -91,84 +121,23 @@ public abstract class AbstractCassandraConfiguration extends AbstractSessionConf SessionFactoryFactoryBean bean = new SessionFactoryFactoryBean(); + // Initialize the CqlSession reference first since it is required, or must not be null. bean.setSession(cqlSession); - bean.setConverter(beanFactory.getBean(CassandraConverter.class)); - bean.setSchemaAction(getSchemaAction()); - bean.setKeyspacePopulator(keyspacePopulator()); + bean.setConverter(requireBeanOfType(CassandraConverter.class)); bean.setKeyspaceCleaner(keyspaceCleaner()); + bean.setKeyspacePopulator(keyspacePopulator()); + bean.setSchemaAction(getSchemaAction()); return bean; } /** - * Creates a {@link KeyspacePopulator} to initialize the keyspace. - * - * @return the {@link KeyspacePopulator} or {@code null} if none configured. - * @see org.springframework.data.cassandra.core.cql.session.init.ResourceKeyspacePopulator - */ - @Nullable - protected KeyspacePopulator keyspacePopulator() { - return null; - } - - /** - * Creates a {@link KeyspacePopulator} to cleanup the keyspace. - * - * @return the {@link KeyspacePopulator} or {@code null} if none configured. - * @see org.springframework.data.cassandra.core.cql.session.init.ResourceKeyspacePopulator - */ - @Nullable - protected KeyspacePopulator keyspaceCleaner() { - return null; - } - - /** - * Creates a {@link CassandraConverter} using the configured {@link #cassandraMapping()}. Will apply all specified - * {@link #customConversions()}. - * - * @return {@link CassandraConverter} used to convert Java and Cassandra value types during the mapping process. - * @see #cassandraMapping() - * @see #customConversions() + * Creates a {@link CassandraAdminTemplate}. */ @Bean - public CassandraConverter cassandraConverter() { - - MappingCassandraConverter mappingCassandraConverter = new MappingCassandraConverter( - beanFactory.getBean(CassandraMappingContext.class)); - - mappingCassandraConverter.setCustomConversions(beanFactory.getBean(CassandraCustomConversions.class)); - - return mappingCassandraConverter; - } - - /** - * Return the {@link MappingContext} instance to map Entities to properties. - * - * @throws ClassNotFoundException if the Cassandra Entity class type identified by name cannot be found during the - * scan. - * @see CassandraMappingContext - */ - @Bean - public CassandraMappingContext cassandraMapping() throws ClassNotFoundException { - - UserTypeResolver userTypeResolver = new SimpleUserTypeResolver(getRequiredSession(), - CqlIdentifier.fromCql(getKeyspaceName())); - - CassandraMappingContext mappingContext = new CassandraMappingContext(userTypeResolver, - SimpleTupleTypeFactory.DEFAULT); - - Optional.ofNullable(this.beanClassLoader).ifPresent(mappingContext::setBeanClassLoader); - - mappingContext.setInitialEntitySet(getInitialEntitySet()); - - CustomConversions customConversions = beanFactory.getBean(CustomConversions.class); - - mappingContext.setCustomConversions(customConversions); - mappingContext.setSimpleTypeHolder(customConversions.getSimpleTypeHolder()); - mappingContext.setCodecRegistry(getRequiredSession().getContext().getCodecRegistry()); - - return mappingContext; + public CassandraAdminTemplate cassandraTemplate() { + return new CassandraAdminTemplate(getRequiredSessionFactory(), requireBeanOfType(CassandraConverter.class)); } /** @@ -200,11 +169,35 @@ public abstract class AbstractCassandraConfiguration extends AbstractSessionConf } /** - * Creates a {@link CassandraAdminTemplate}. + * Returns the initialized {@link CqlSession} instance. + * + * @return the {@link CqlSession}. + * @throws IllegalStateException if the session factory is not initialized. */ - @Bean - public CassandraAdminTemplate cassandraTemplate() { - return new CassandraAdminTemplate(getRequiredSessionFactory(), beanFactory.getBean(CassandraConverter.class)); + protected SessionFactory getRequiredSessionFactory() { + return requireBeanOfType(SessionFactory.class); + } + + /** + * Creates a {@link KeyspacePopulator} to cleanup the keyspace. + * + * @return the {@link KeyspacePopulator} or {@code null} if none configured. + * @see org.springframework.data.cassandra.core.cql.session.init.ResourceKeyspacePopulator + */ + @Nullable + protected KeyspacePopulator keyspaceCleaner() { + return null; + } + + /** + * Creates a {@link KeyspacePopulator} to initialize the keyspace. + * + * @return the {@link KeyspacePopulator} or {@code null} if none configured. + * @see org.springframework.data.cassandra.core.cql.session.init.ResourceKeyspacePopulator + */ + @Nullable + protected KeyspacePopulator keyspacePopulator() { + return null; } @Override @@ -212,10 +205,8 @@ public abstract class AbstractCassandraConfiguration extends AbstractSessionConf this.beanClassLoader = classLoader; } - @Override - public void setBeanFactory(BeanFactory beanFactory) throws BeansException { - this.beanFactory = beanFactory; - super.setBeanFactory(beanFactory); + protected Optional getBeanClassLoader() { + return Optional.ofNullable(this.beanClassLoader); } /** 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 de6707e68..849e86765 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 @@ -31,6 +31,7 @@ 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; @@ -52,6 +53,7 @@ import com.typesafe.config.ConfigFactory; * @author Matthew T. Adams * @author John Blum * @author Mark Paluch + * @see org.springframework.beans.factory.BeanFactoryAware * @see org.springframework.context.annotation.Configuration */ @Configuration @@ -59,6 +61,58 @@ public abstract class AbstractSessionConfiguration implements BeanFactoryAware { private @Nullable BeanFactory beanFactory; + /** + * Configures a reference to the {@link BeanFactory}. + * + * @param beanFactory reference to the {@link BeanFactory}. + * @throws BeansException if the {@link BeanFactory} could not be initialized. + * @see org.springframework.beans.factory.BeanFactory + */ + @Override + public void setBeanFactory(BeanFactory beanFactory) throws BeansException { + this.beanFactory = beanFactory; + } + + /** + * Returns the configured reference to the {@link BeanFactory}. + * + * @return the configured reference to the {@link BeanFactory}. + * @throws IllegalStateException if the {@link BeanFactory} reference was not configured. + * @see org.springframework.beans.factory.BeanFactory + */ + protected BeanFactory getBeanFactory() { + + Assert.state(this.beanFactory != null, "BeanFactory not initialized"); + + return this.beanFactory; + } + + /** + * Gets a required bean of the provided {@link Class type} from the {@link BeanFactory}. + * + * @param {@link Class parameterized clas type} of the bean. + * @param beanType {@link Class type} of the bean. + * @return a required bean of the given {@link Class type} from the {@link BeanFactory}. + * @see org.springframework.beans.factory.BeanFactory#getBean(Class) + * @see #getBeanFactory() + */ + protected T requireBeanOfType(@NonNull Class beanType) { + return getBeanFactory().getBean(beanType); + } + + /** + * Returns the {@link String name} of the cluster. + * + * @return the {@link String cluster name}; may be {@literal null}. + * @deprecated since 3.0, use {@link #getSessionName()} instead. + * @since 1.5 + */ + @Nullable + @Deprecated + protected String getClusterName() { + return null; + } + /** * Return the name of the keyspace to connect to. * @@ -67,39 +121,13 @@ public abstract class AbstractSessionConfiguration implements BeanFactoryAware { protected abstract String getKeyspaceName(); /** - * Returns the initialized {@link CqlSession} instance. + * Returns the local data center name used for + * {@link com.datastax.oss.driver.api.core.loadbalancing.LoadBalancingPolicy}. * - * @return the {@link CqlSession}. - * @throws IllegalStateException if the session factory is not initialized. - */ - protected SessionFactory getRequiredSessionFactory() { - - ObjectProvider beanProvider = beanFactory.getBeanProvider(SessionFactory.class); - - return beanProvider.getIfAvailable(() -> new DefaultSessionFactory(beanFactory.getBean(CqlSession.class))); - } - - /** - * Returns the {@link SessionBuilderConfigurer}. - * - * @return the {@link SessionBuilderConfigurer}; may be {@literal null}. - * @since 1.5 + * @return the local data center name. */ @Nullable - protected SessionBuilderConfigurer getSessionBuilderConfigurer() { - return null; - } - - /** - * Returns the cluster name. - * - * @return the cluster name; may be {@literal null}. - * @since 1.5 - * @deprecated since 3.0, use {@link #getSessionName()} instead. - */ - @Nullable - @Deprecated - protected String getClusterName() { + protected String getLocalDataCenter() { return null; } @@ -163,12 +191,36 @@ public abstract class AbstractSessionConfiguration implements BeanFactoryAware { } /** - * Returns the local data center name used for - * {@link com.datastax.oss.driver.api.core.loadbalancing.LoadBalancingPolicy}. + * Returns the initialized {@link CqlSession} instance. * - * @return the local data center name. + * @return the {@link CqlSession}. + * @throws IllegalStateException if the session factory is not initialized. */ - protected String getLocalDataCenter() { + protected CqlSession getRequiredSession() { + return requireBeanOfType(CqlSession.class); + } + + /** + * Returns the initialized {@link CqlSession} instance. + * + * @return the {@link CqlSession}. + * @throws IllegalStateException if the session factory is not initialized. + */ + protected SessionFactory getRequiredSessionFactory() { + + ObjectProvider beanProvider = getBeanFactory().getBeanProvider(SessionFactory.class); + + return beanProvider.getIfAvailable(() -> new DefaultSessionFactory(requireBeanOfType(CqlSession.class))); + } + + /** + * Returns the {@link SessionBuilderConfigurer}. + * + * @return the {@link SessionBuilderConfigurer}; may be {@literal null}. + * @since 1.5 + */ + @Nullable + protected SessionBuilderConfigurer getSessionBuilderConfigurer() { return null; } @@ -176,9 +228,9 @@ public abstract class AbstractSessionConfiguration implements BeanFactoryAware { * Returns the list of startup scripts to be run after {@link #getKeyspaceCreations() keyspace creations} and after * initialization in the {@code system} keyspace. * - * @return the list of startup scripts, may be empty but never {@code null}. - * @deprecated since 3.0, declare a - * {@link org.springframework.data.cassandra.core.cql.session.init.SessionFactoryInitializer} bean. + * @return the list of startup scripts, may be {@link Collections#emptyList() empty} but never {@literal null}. + * @deprecated since 3.0; Declare a + * {@link org.springframework.data.cassandra.core.cql.session.init.SessionFactoryInitializer} bean instead. */ @Deprecated protected List getStartupScripts() { @@ -189,28 +241,15 @@ public abstract class AbstractSessionConfiguration implements BeanFactoryAware { * Returns the list of shutdown scripts to be run after {@link #getKeyspaceDrops() keyspace drops} and right before * shutdown in the {@code system} keyspace. * - * @return the list of shutdown scripts, may be empty but never {@code null}. - * @deprecated since 3.0, declare a - * {@link org.springframework.data.cassandra.core.cql.session.init.SessionFactoryInitializer} bean. + * @return the list of shutdown scripts, may be {@link Collections#emptyList() empty} but never {@literal null}. + * @deprecated since 3.0; Declare a + * {@link org.springframework.data.cassandra.core.cql.session.init.SessionFactoryInitializer} bean instead. */ @Deprecated protected List getShutdownScripts() { return Collections.emptyList(); } - /** - * Returns the initialized {@link CqlSession} instance. - * - * @return the {@link CqlSession}. - * @throws IllegalStateException if the session factory is not initialized. - */ - protected CqlSession getRequiredSession() { - - Assert.state(beanFactory != null, "BeanFactory not initialized"); - - return beanFactory.getBean(CqlSession.class); - } - /** * Creates a {@link CqlSessionFactoryBean} that provides a Cassandra {@link CqlSession}. * @@ -225,22 +264,19 @@ public abstract class AbstractSessionConfiguration implements BeanFactoryAware { CqlSessionFactoryBean bean = new CqlSessionFactoryBean(); bean.setContactPoints(getContactPoints()); - bean.setPort(getPort()); - bean.setLocalDatacenter(getLocalDataCenter()); - bean.setKeyspaceCreations(getKeyspaceCreations()); bean.setKeyspaceDrops(getKeyspaceDrops()); - - bean.setSessionSessionBuilderConfigurer(getBuilderConfigurer()); - bean.setKeyspaceName(getKeyspaceName()); bean.setKeyspaceStartupScripts(getStartupScripts()); bean.setKeyspaceShutdownScripts(getShutdownScripts()); + bean.setLocalDatacenter(getLocalDataCenter()); + bean.setPort(getPort()); + bean.setSessionBuilderConfigurer(getSessionBuilderConfigurerWrapper()); return bean; } - private SessionBuilderConfigurer getBuilderConfigurer() { + private SessionBuilderConfigurer getSessionBuilderConfigurerWrapper() { SessionBuilderConfigurer configurer = getSessionBuilderConfigurer(); @@ -252,18 +288,23 @@ public abstract class AbstractSessionConfiguration implements BeanFactoryAware { if (StringUtils.hasText(getClusterName())) { options.add(DefaultDriverOption.SESSION_NAME, getClusterName()); - } else if (StringUtils.hasText(getSessionName())) { + } + else if (StringUtils.hasText(getSessionName())) { options.add(DefaultDriverOption.SESSION_NAME, getSessionName()); } CompressionType compressionType = getCompressionType(); + if (compressionType != null) { options.add(DefaultDriverOption.PROTOCOL_COMPRESSION, compressionType); } ConfigFactory.invalidateCaches(); - return ConfigFactory.defaultOverrides().withFallback(options.build()) - .withFallback(ConfigFactory.defaultReference()).resolve(); + + return ConfigFactory.defaultOverrides() + .withFallback(options.build()) + .withFallback(ConfigFactory.defaultReference()) + .resolve(); }, DefaultDriverConfigLoader.DEFAULT_ROOT_PATH); @@ -288,11 +329,6 @@ public abstract class AbstractSessionConfiguration implements BeanFactoryAware { return new CqlTemplate(getRequiredSessionFactory()); } - @Override - public void setBeanFactory(BeanFactory beanFactory) throws BeansException { - this.beanFactory = beanFactory; - } - private static class CassandraDriverOptions { private final Map options = new LinkedHashMap<>(); @@ -303,21 +339,10 @@ public abstract class AbstractSessionConfiguration implements BeanFactoryAware { return this; } - private CassandraDriverOptions add(DriverOption option, int value) { - return add(option, String.valueOf(value)); - } - private CassandraDriverOptions add(DriverOption option, Enum value) { return add(option, value.name()); } - private CassandraDriverOptions add(DriverOption option, List values) { - for (int i = 0; i < values.size(); i++) { - this.options.put(String.format("%s.%s", createKeyFor(option), i), values.get(i)); - } - return this; - } - private Config build() { return ConfigFactory.parseMap(this.options, "Environment"); } @@ -326,5 +351,4 @@ public abstract class AbstractSessionConfiguration implements BeanFactoryAware { return String.format("%s.%s", DefaultDriverConfigLoader.DEFAULT_ROOT_PATH, option.getPath()); } } - } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/CqlSessionFactoryBean.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/CqlSessionFactoryBean.java index dd62adb1c..32a0c75ba 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/CqlSessionFactoryBean.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/CqlSessionFactoryBean.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.springframework.data.cassandra.config; import java.net.InetSocketAddress; @@ -70,34 +69,28 @@ import com.datastax.oss.driver.api.core.CqlSessionBuilder; public class CqlSessionFactoryBean implements FactoryBean, InitializingBean, DisposableBean, PersistenceExceptionTranslator { - public static final int DEFAULT_PORT = 9042; - public static final String DEFAULT_CONTACT_POINTS = "localhost"; - - protected final Logger logger = LoggerFactory.getLogger(getClass()); - private static final boolean DEFAULT_CREATE_IF_NOT_EXISTS = false; private static final boolean DEFAULT_DROP_TABLES = false; private static final boolean DEFAULT_DROP_UNUSED_TABLES = false; + + public static final int DEFAULT_PORT = 9042; + private static final CassandraExceptionTranslator EXCEPTION_TRANSLATOR = new CassandraExceptionTranslator(); - private @Nullable CqlSession systemSession; - private @Nullable CqlSession session; + public static final String CASSANDRA_SYSTEM_SESSION = "system"; + public static final String DEFAULT_CONTACT_POINTS = "localhost"; - private String contactPoints = DEFAULT_CONTACT_POINTS; private int port = DEFAULT_PORT; - private @Nullable String password; - private @Nullable String username; - private @Nullable String keyspaceName; - private @Nullable String localDatacenter; + private @Nullable CassandraConverter converter; - private @Nullable SessionBuilderConfigurer sessionSessionBuilderConfigurer; + private @Nullable CqlSession session; + private @Nullable CqlSession systemSession; private List keyspaceActions = new ArrayList<>(); - private Set keyspaceSpecifications = new HashSet<>(); - private List keyspaceCreations = new ArrayList<>(); private List keyspaceAlterations = new ArrayList<>(); + private List keyspaceCreations = new ArrayList<>(); private List keyspaceDrops = new ArrayList<>(); private List keyspaceStartupScripts = new ArrayList<>(); @@ -106,15 +99,26 @@ public class CqlSessionFactoryBean private List startupScripts = Collections.emptyList(); private List shutdownScripts = Collections.emptyList(); - private @Nullable CassandraConverter converter; + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + private Set keyspaceSpecifications = new HashSet<>(); private SchemaAction schemaAction = SchemaAction.NONE; + private @Nullable SessionBuilderConfigurer sessionBuilderConfigurer; + + private String contactPoints = DEFAULT_CONTACT_POINTS; + + private @Nullable String keyspaceName; + private @Nullable String localDatacenter; + private @Nullable String password; + private @Nullable String username; + /** * Null-safe operation to determine whether the Cassandra {@link CqlSession} is connected or not. * * @return a boolean value indicating whether the Cassandra {@link CqlSession} is connected. - * @see Session#isClosed() + * @see com.datastax.oss.driver.api.core.session.Session#isClosed() * @see #getObject() */ public boolean isConnected() { @@ -134,6 +138,15 @@ public class CqlSessionFactoryBean this.contactPoints = contactPoints; } + /** + * Sets the name of the local datacenter. + * + * @param localDatacenter a String indicating the name of the local datacenter. + */ + public void setLocalDatacenter(@Nullable String localDatacenter) { + this.localDatacenter = localDatacenter; + } + /** * Set the port for the contact points. Default is {@code 9042}, see {@link #DEFAULT_PORT}. * @@ -161,6 +174,82 @@ public class CqlSessionFactoryBean this.password = password; } + /** + * Set the {@link CassandraConverter} to use. Schema actions will derive table and user type information from the + * {@link CassandraMappingContext} inside {@code converter}. + * + * @param converter must not be {@literal null}. + * @deprecated Use {@link CassandraSessionFactoryBean} with + * {@link CassandraSessionFactoryBean#setConverter(CassandraConverter)} instead. + */ + @Deprecated + public void setConverter(CassandraConverter converter) { + + Assert.notNull(converter, "CassandraConverter must not be null"); + + this.converter = converter; + } + + /** + * @return the configured {@link CassandraConverter}. + */ + @Nullable + public CassandraConverter getConverter() { + return this.converter; + } + + /** + * Set a {@link List} of {@link KeyspaceActions} to be executed on initialization. Keyspace actions may contain create + * and drop specifications. + * + * @param keyspaceActions the {@link List} of {@link KeyspaceActions}. + */ + public void setKeyspaceActions(List keyspaceActions) { + this.keyspaceActions = new ArrayList<>(keyspaceActions); + } + + /** + * @return the {@link List} of {@link KeyspaceActions}. + */ + public List getKeyspaceActions() { + return Collections.unmodifiableList(this.keyspaceActions); + } + + /** + * Set a {@link List} of {@link AlterKeyspaceSpecification alter keyspace specifications} that are executed when this + * factory is {@link #afterPropertiesSet() initialized}. {@link AlterKeyspaceSpecification Alter keyspace + * specifications} are executed on a system session with no keyspace set, before executing + * {@link #setStartupScripts(List)}. + * + * @param specifications the {@link List} of {@link CreateKeyspaceSpecification create keyspace specifications}. + */ + public void setKeyspaceAlterations(List specifications) { + this.keyspaceAlterations = new ArrayList<>(specifications); + } + + /** + * Set a {@link List} of {@link CreateKeyspaceSpecification create keyspace specifications} that are executed when + * this factory is {@link #afterPropertiesSet() initialized}. {@link CreateKeyspaceSpecification Create keyspace + * specifications} are executed on a system session with no keyspace set, before executing + * {@link #setStartupScripts(List)}. + * + * @param specifications the {@link List} of {@link CreateKeyspaceSpecification create keyspace specifications}. + */ + public void setKeyspaceCreations(List specifications) { + this.keyspaceCreations = new ArrayList<>(specifications); + } + + /** + * Set a {@link List} of {@link DropKeyspaceSpecification drop keyspace specifications} that are executed when this + * factory is {@link #destroy() destroyed}. {@link DropKeyspaceSpecification Drop keyspace specifications} are + * executed on a system session with no keyspace set, before executing {@link #setShutdownScripts(List)}. + * + * @param specifications the {@link List} of {@link DropKeyspaceSpecification drop keyspace specifications}. + */ + public void setKeyspaceDrops(List specifications) { + this.keyspaceDrops = new ArrayList<>(specifications); + } + /** * Sets the name of the Cassandra Keyspace to connect to. Passing {@literal null} will cause the Cassandra System * Keyspace to be used. @@ -183,23 +272,6 @@ public class CqlSessionFactoryBean return this.keyspaceName; } - /** - * @return the {@link List} of {@link KeyspaceActions}. - */ - public List getKeyspaceActions() { - return Collections.unmodifiableList(this.keyspaceActions); - } - - /** - * Set a {@link List} of {@link KeyspaceActions} to be executed on initialization. Keyspace actions may contain create - * and drop specifications. - * - * @param keyspaceActions the {@link List} of {@link KeyspaceActions}. - */ - public void setKeyspaceActions(List keyspaceActions) { - this.keyspaceActions = new ArrayList<>(keyspaceActions); - } - /** * @param keyspaceSpecifications The {@link KeyspaceActionSpecification} to set. */ @@ -208,38 +280,10 @@ public class CqlSessionFactoryBean } /** - * Set a {@link List} of {@link CreateKeyspaceSpecification create keyspace specifications} that are executed when - * this factory is {@link #afterPropertiesSet() initialized}. {@link CreateKeyspaceSpecification Create keyspace - * specifications} are executed on a system session with no keyspace set, before executing - * {@link #setStartupScripts(List)}. - * - * @param specifications the {@link List} of {@link CreateKeyspaceSpecification create keyspace specifications}. + * @return the {@link KeyspaceActionSpecification} associated with this factory. */ - public void setKeyspaceCreations(List specifications) { - this.keyspaceCreations = new ArrayList<>(specifications); - } - - /** - * Set a {@link List} of {@link AlterKeyspaceSpecification alter keyspace specifications} that are executed when this - * factory is {@link #afterPropertiesSet() initialized}. {@link AlterKeyspaceSpecification Alter keyspace - * specifications} are executed on a system session with no keyspace set, before executing - * {@link #setStartupScripts(List)}. - * - * @param specifications the {@link List} of {@link CreateKeyspaceSpecification create keyspace specifications}. - */ - public void setKeyspaceAlterations(List specifications) { - this.keyspaceAlterations = new ArrayList<>(specifications); - } - - /** - * Set a {@link List} of {@link DropKeyspaceSpecification drop keyspace specifications} that are executed when this - * factory is {@link #destroy() destroyed}. {@link DropKeyspaceSpecification Drop keyspace specifications} are - * executed on a system session with no keyspace set, before executing {@link #setShutdownScripts(List)}. - * - * @param specifications the {@link List} of {@link DropKeyspaceSpecification drop keyspace specifications}. - */ - public void setKeyspaceDrops(List specifications) { - this.keyspaceDrops = new ArrayList<>(specifications); + public Set getKeyspaceSpecifications() { + return Collections.unmodifiableSet(this.keyspaceSpecifications); } /** @@ -265,19 +309,37 @@ public class CqlSessionFactoryBean } /** - * @return the {@link KeyspaceActionSpecification} associated with this factory. + * @return the {@link CassandraMappingContext}. */ - public Set getKeyspaceSpecifications() { - return Collections.unmodifiableSet(this.keyspaceSpecifications); + protected CassandraMappingContext getMappingContext() { + + CassandraConverter converter = getConverter(); + + Assert.state(converter != null, "CassandraConverter was not properly initialized"); + + return converter.getMappingContext(); } /** - * Sets the name of the local datacenter. + * Set the {@link SchemaAction}. * - * @param localDatacenter a String indicating the name of the local datacenter. + * @param schemaAction must not be {@literal null}. + * @deprecated Use {@link CassandraSessionFactoryBean} with + * {@link CassandraSessionFactoryBean#setSchemaAction(SchemaAction)} instead. */ - public void setLocalDatacenter(@Nullable String localDatacenter) { - this.localDatacenter = localDatacenter; + @Deprecated + public void setSchemaAction(SchemaAction schemaAction) { + + Assert.notNull(schemaAction, "SchemaAction must not be null"); + + this.schemaAction = schemaAction; + } + + /** + * @return the {@link SchemaAction}. + */ + public SchemaAction getSchemaAction() { + return this.schemaAction; } /** @@ -285,7 +347,7 @@ public class CqlSessionFactoryBean * * @return a reference to the connected Cassandra {@link CqlSession}. * @throws IllegalStateException if the Cassandra {@link CqlSession} was not properly initialized. - * @see Session + * @see com.datastax.oss.driver.api.core.CqlSession */ protected CqlSession getSession() { @@ -300,10 +362,10 @@ public class CqlSessionFactoryBean * Sets the {@link SessionBuilderConfigurer} to configure the * {@link com.datastax.oss.driver.api.core.session.SessionBuilder}. * - * @param sessionSessionBuilderConfigurer + * @param sessionBuilderConfigurer */ - public void setSessionSessionBuilderConfigurer(@Nullable SessionBuilderConfigurer sessionSessionBuilderConfigurer) { - this.sessionSessionBuilderConfigurer = sessionSessionBuilderConfigurer; + public void setSessionBuilderConfigurer(@Nullable SessionBuilderConfigurer sessionBuilderConfigurer) { + this.sessionBuilderConfigurer = sessionBuilderConfigurer; } /** @@ -354,64 +416,6 @@ public class CqlSessionFactoryBean return Collections.unmodifiableList(this.shutdownScripts); } - /** - * Set the {@link CassandraConverter} to use. Schema actions will derive table and user type information from the - * {@link CassandraMappingContext} inside {@code converter}. - * - * @param converter must not be {@literal null}. - * @deprecated Use {@link CassandraSessionFactoryBean} with - * {@link CassandraSessionFactoryBean#setConverter(CassandraConverter)} instead. - */ - @Deprecated - public void setConverter(CassandraConverter converter) { - - Assert.notNull(converter, "CassandraConverter must not be null"); - - this.converter = converter; - } - - /** - * @return the {@link CassandraConverter}. - */ - @Nullable - public CassandraConverter getConverter() { - return this.converter; - } - - /** - * @return the {@link CassandraMappingContext}. - */ - protected CassandraMappingContext getMappingContext() { - - CassandraConverter converter = getConverter(); - - Assert.state(converter != null, "CassandraConverter was not properly initialized"); - - return converter.getMappingContext(); - } - - /** - * Set the {@link SchemaAction}. - * - * @param schemaAction must not be {@literal null}. - * @deprecated Use {@link CassandraSessionFactoryBean} with - * {@link CassandraSessionFactoryBean#setSchemaAction(SchemaAction)} instead. - */ - @Deprecated - public void setSchemaAction(SchemaAction schemaAction) { - - Assert.notNull(schemaAction, "SchemaAction must not be null"); - - this.schemaAction = schemaAction; - } - - /** - * @return the {@link SchemaAction}. - */ - public SchemaAction getSchemaAction() { - return this.schemaAction; - } - /* * (non-Javadoc) * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet() @@ -420,35 +424,65 @@ public class CqlSessionFactoryBean public void afterPropertiesSet() { CqlSessionBuilder sessionBuilder = buildBuilder(); + this.systemSession = buildSystemSession(sessionBuilder); initializeCluster(this.systemSession); this.session = buildSession(sessionBuilder); - executeScripts(getStartupScripts().stream(), this.session); + executeCql(getStartupScripts().stream(), this.session); performSchemaAction(); + this.systemSession.refreshSchema(); this.session.refreshSchema(); } - /** - * Build the system session. - * - * @param sessionBuilder - * @return - */ - protected CqlSession buildSystemSession(CqlSessionBuilder sessionBuilder) { - return sessionBuilder.withKeyspace("system").build(); + protected CqlSessionBuilder buildBuilder() { + + Assert.hasText(this.contactPoints, "At least one server is required"); + + CqlSessionBuilder sessionBuilder = CqlSession.builder(); + + StringUtils.commaDelimitedListToSet(this.contactPoints).forEach(host -> + sessionBuilder.addContactPoint(InetSocketAddress.createUnresolved(host, this.port))); + + if (StringUtils.hasText(this.username)) { + sessionBuilder.withAuthCredentials(this.username, this.password); + } + + if (StringUtils.hasText(this.localDatacenter)) { + sessionBuilder.withLocalDatacenter(this.localDatacenter); + } + + return this.sessionBuilderConfigurer != null + ? this.sessionBuilderConfigurer.configure(sessionBuilder) + : sessionBuilder; } /** - * Build the keyspace session. + * Build the Cassandra {@link CqlSession System Session}. * - * @param sessionBuilder - * @return + * @param sessionBuilder {@link CqlSessionBuilder} used to a build a Cassandra {@link CqlSession}. + * @return the built Cassandra {@link CqlSession System Session}. + * @see com.datastax.oss.driver.api.core.CqlSessionBuilder + * @see com.datastax.oss.driver.api.core.CqlSession + */ + protected CqlSession buildSystemSession(CqlSessionBuilder sessionBuilder) { + return sessionBuilder.withKeyspace(CASSANDRA_SYSTEM_SESSION).build(); + } + + /** + * Build a {@link CqlSession Session} to the user-defined {@literal Keyspace} or the default {@literal Keyspace} + * if the user did not specify a {@literal Keyspace} by {@link String name}. + * + * @param sessionBuilder {@link CqlSessionBuilder} used to a build a Cassandra {@link CqlSession}. + * @return the built {@link CqlSession} to the user-defined {@literal Keyspace}. + * @see com.datastax.oss.driver.api.core.CqlSessionBuilder + * @see com.datastax.oss.driver.api.core.CqlSession */ protected CqlSession buildSession(CqlSessionBuilder sessionBuilder) { + if (StringUtils.hasText(getKeyspaceName())) { sessionBuilder.withKeyspace(getKeyspaceName()); } @@ -456,82 +490,43 @@ public class CqlSessionFactoryBean return sessionBuilder.build(); } - /* (non-Javadoc) - * @see org.springframework.beans.factory.DisposableBean#destroy() - */ - @Override - public void destroy() { - - if (session != null) { - - executeScripts(getShutdownScripts().stream(), this.session); - - executeSpecsAndScripts(keyspaceDrops, keyspaceShutdownScripts, this.systemSession); - closeSystemSession(); - closeSession(); - } - } - - /** - * Close the regular session object. - */ - protected void closeSession() { - session.close(); - } - - /** - * Close the system session object. - */ - protected void closeSystemSession() { - systemSession.close(); - } - - protected CqlSessionBuilder buildBuilder() { - - Assert.hasText(this.contactPoints, "At least one server is required"); - - CqlSessionBuilder builder = CqlSession.builder(); - StringUtils.commaDelimitedListToSet(this.contactPoints).stream().forEach(host -> { - builder.addContactPoint(InetSocketAddress.createUnresolved(host, this.port)); - }); - - if (StringUtils.hasText(this.username)) { - builder.withAuthCredentials(this.username, this.password); - } - - if (StringUtils.hasText(this.localDatacenter)) { - builder.withLocalDatacenter(this.localDatacenter); - } - - if (this.sessionSessionBuilderConfigurer != null) { - return this.sessionSessionBuilderConfigurer.configure(builder); - } - - return builder; - } - private void initializeCluster(CqlSession session) { - generateSpecificationsFromFactoryDeclarations(); + generateSpecificationsFromFactoryBeanDeclarations(); - List startupSpecifications = new ArrayList<>( - this.keyspaceCreations.size() + this.keyspaceAlterations.size()); + List keyspaceStartupSpecifications = + new ArrayList<>(this.keyspaceCreations.size() + this.keyspaceAlterations.size()); - startupSpecifications.addAll(this.keyspaceCreations); - startupSpecifications.addAll(this.keyspaceAlterations); + keyspaceStartupSpecifications.addAll(this.keyspaceCreations); + keyspaceStartupSpecifications.addAll(this.keyspaceAlterations); - executeSpecsAndScripts(startupSpecifications, this.keyspaceStartupScripts, session); + executeSpecificationsAndScripts(keyspaceStartupSpecifications, this.keyspaceStartupScripts, session); } - private void executeSpecsAndScripts(List keyspaceActionSpecifications, - List scripts, CqlSession session) { + /** + * Evaluates the contents of all the {@link KeyspaceActionSpecificationFactoryBean}s + * and generates the proper {@link KeyspaceActionSpecification}s from them. + */ + private void generateSpecificationsFromFactoryBeanDeclarations() { - if (!CollectionUtils.isEmpty(keyspaceActionSpecifications) || !CollectionUtils.isEmpty(scripts)) { + generateSpecifications(this.keyspaceSpecifications); + this.keyspaceActions.forEach(actions -> generateSpecifications(actions.getActions())); + } - Stream keyspaceActions = keyspaceActionSpecifications.stream().map(this::toCql); + private void generateSpecifications(Collection specifications) { - executeScripts(Stream.concat(keyspaceActions, scripts.stream()), session); - } + specifications.forEach(specification -> { + + if (specification instanceof AlterKeyspaceSpecification) { + this.keyspaceAlterations.add((AlterKeyspaceSpecification) specification); + } + else if (specification instanceof CreateKeyspaceSpecification) { + this.keyspaceCreations.add((CreateKeyspaceSpecification) specification); + } + else if (specification instanceof DropKeyspaceSpecification) { + this.keyspaceDrops.add((DropKeyspaceSpecification) specification); + } + }); } /** @@ -567,27 +562,28 @@ public class CqlSessionFactoryBean * Perform schema actions. * * @param drop {@literal true} to drop types/tables. - * @param dropUnused {@literal true} to drop unused types/tables (i.e. types/tables not know to be used by - * {@link CassandraMappingContext}). - * @param ifNotExists {@literal true} to perform creations fail-safe by adding {@code IF NOT EXISTS} to each creation - * statement. + * @param dropUnused {@literal true} to drop unused types/tables (i.e. types/tables not known to be used by + * the {@link CassandraMappingContext}). + * @param ifNotExists {@literal true} to perform fail-safe creations by adding {@code IF NOT EXISTS} + * to each creation statement. */ protected void createTables(boolean drop, boolean dropUnused, boolean ifNotExists) { - CassandraAdminTemplate adminTemplate = new CassandraAdminTemplate(this.session, converter); + CassandraAdminTemplate adminTemplate = new CassandraAdminTemplate(this.session, this.converter); + performSchemaActions(drop, dropUnused, ifNotExists, adminTemplate); } private void performSchemaActions(boolean drop, boolean dropUnused, boolean ifNotExists, CassandraAdminOperations adminOperations) { - CassandraPersistentEntitySchemaCreator schemaCreator = new CassandraPersistentEntitySchemaCreator( - getMappingContext(), adminOperations); + CassandraPersistentEntitySchemaCreator schemaCreator = + new CassandraPersistentEntitySchemaCreator(getMappingContext(), adminOperations); if (drop) { - CassandraPersistentEntitySchemaDropper schemaDropper = new CassandraPersistentEntitySchemaDropper( - getMappingContext(), adminOperations); + CassandraPersistentEntitySchemaDropper schemaDropper = + new CassandraPersistentEntitySchemaDropper(getMappingContext(), adminOperations); schemaDropper.dropTables(dropUnused); schemaDropper.dropUserTypes(dropUnused); @@ -598,6 +594,35 @@ public class CqlSessionFactoryBean schemaCreator.createIndexes(ifNotExists); } + /* + * (non-Javadoc) + * @see org.springframework.beans.factory.DisposableBean#destroy() + */ + @Override + public void destroy() { + + if (this.session != null) { + executeCql(getShutdownScripts().stream(), this.session); + executeSpecificationsAndScripts(this.keyspaceDrops, this.keyspaceShutdownScripts, this.systemSession); + closeSession(); + closeSystemSession(); + } + } + + /** + * Close the regular session object. + */ + protected void closeSession() { + this.session.close(); + } + + /** + * Close the system session object. + */ + protected void closeSystemSession() { + this.systemSession.close(); + } + /* * (non-Javadoc) * @see org.springframework.beans.factory.FactoryBean#getObject() @@ -626,52 +651,54 @@ public class CqlSessionFactoryBean } /** - * Executes the given Cassandra CQL scripts. The {@link CqlSession} must be connected when this method is called. + * Executes the given, raw Cassandra CQL scripts. + * + * The {@link CqlSession} must be connected when this method is called. + * + * @see com.datastax.oss.driver.api.core.CqlSession#execute(String) */ - private void executeScripts(Stream scripts, CqlSession session) { + private void executeCql(Stream cql, CqlSession session) { - scripts.forEach(script -> { - logger.info("executing raw CQL [{}]", script); - session.execute(script); + cql.forEach(query -> { + this.logger.info("Executing CQL [{}]", query); + session.execute(query); }); } + private void executeSpecificationsAndScripts(List keyspaceActionSpecifications, + List keyspaceCqlScripts, CqlSession session) { + + if (!CollectionUtils.isEmpty(keyspaceActionSpecifications) || !CollectionUtils.isEmpty(keyspaceCqlScripts)) { + + Stream keyspaceActionSpecificationsStream = keyspaceActionSpecifications.stream().map(this::toCql); + Stream keyspaceCqlScriptsStream = keyspaceCqlScripts.stream(); + Stream cql = Stream.concat(keyspaceActionSpecificationsStream, keyspaceCqlScriptsStream); + + executeCql(cql, session); + } + } + /** - * Evaluates the contents of all the KeyspaceSpecificationFactoryBean and generates the proper KeyspaceSpecification - * from them. + * Converts the {@link KeyspaceActionSpecification} to {@link String CQL}. + * + * @param specification {@link KeyspaceActionSpecification} to convert to {@link String CQL}. + * @return a {@link String} containing the CQL for the given {@link KeyspaceActionSpecification}. + * @see org.springframework.data.cassandra.core.cql.keyspace.KeyspaceActionSpecification */ - private void generateSpecificationsFromFactoryDeclarations() { - - generateSpecifications(this.keyspaceSpecifications); - this.keyspaceActions.forEach(actions -> generateSpecifications(actions.getActions())); - } - - private void generateSpecifications(Collection specifications) { - - specifications.forEach(keyspaceActionSpecification -> { - - if (keyspaceActionSpecification instanceof AlterKeyspaceSpecification) { - this.keyspaceAlterations.add((AlterKeyspaceSpecification) keyspaceActionSpecification); - } else if (keyspaceActionSpecification instanceof CreateKeyspaceSpecification) { - this.keyspaceCreations.add((CreateKeyspaceSpecification) keyspaceActionSpecification); - } else if (keyspaceActionSpecification instanceof DropKeyspaceSpecification) { - this.keyspaceDrops.add((DropKeyspaceSpecification) keyspaceActionSpecification); - } - }); - } - private String toCql(KeyspaceActionSpecification specification) { if (specification instanceof AlterKeyspaceSpecification) { return new AlterKeyspaceCqlGenerator((AlterKeyspaceSpecification) specification).toCql(); - } else if (specification instanceof CreateKeyspaceSpecification) { + } + else if (specification instanceof CreateKeyspaceSpecification) { return new CreateKeyspaceCqlGenerator((CreateKeyspaceSpecification) specification).toCql(); - } else if (specification instanceof DropKeyspaceSpecification) { + } + else if (specification instanceof DropKeyspaceSpecification) { return new DropKeyspaceCqlGenerator((DropKeyspaceSpecification) specification).toCql(); } - throw new IllegalArgumentException( - "Unsupported specification type: " + ClassUtils.getQualifiedName(specification.getClass())); + throw new IllegalArgumentException(String.format("Unsupported specification type: %s", + ClassUtils.getQualifiedName(specification.getClass()))); } @Nullable diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/SessionBuilderConfigurer.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/SessionBuilderConfigurer.java index 067d945ec..6454c0115 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/SessionBuilderConfigurer.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/SessionBuilderConfigurer.java @@ -16,25 +16,26 @@ package org.springframework.data.cassandra.config; import com.datastax.oss.driver.api.core.CqlSessionBuilder; -import com.datastax.oss.driver.api.core.session.SessionBuilder; /** - * Configuration callback class to allow a user to apply additional configuration logic to the {@link SessionBuilder}. + * Configuration callback to allow users to implement and apply additional configuration logic to + * the {@link CqlSessionBuilder}. * * @author John Blum * @author Mark Paluch + * @see com.datastax.oss.driver.api.core.CqlSessionBuilder * @since 3.0 - * @see com.datastax.oss.driver.api.core.CqlSession */ @FunctionalInterface public interface SessionBuilderConfigurer { /** - * Apply addition configuration to the {@link SessionBuilder}. + * Apply additional configuration to the Cassandra {@link CqlSessionBuilder}. * - * @param sessionBuilder {@link SessionBuilder} to configure. - * @return the argument to the {@code sessionBuilder} parameter. - * @see SessionBuilder + * @param sessionBuilder {@link CqlSessionBuilder} to configure. + * @return the {@link CqlSessionBuilder} or a decorated {@link CqlSessionBuilder} as required by the caller. + * @see com.datastax.oss.driver.api.core.CqlSessionBuilder */ CqlSessionBuilder configure(CqlSessionBuilder sessionBuilder); + } 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 944b3ffc7..14bcc0c74 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 @@ -46,51 +46,15 @@ public class SessionFactoryFactoryBean extends AbstractFactoryBean