{
/**
- * Gets called by {@link CqlTemplate#execute(String, PreparedStatementCallback)} with a {@link PreparedStatement}.
+ * Gets called by {@link CqlTemplate#execute(String, PreparedStatementCallback)} with an active CQL session and
+ * {@link PreparedStatement}. Does not need to care about closing the session: this will all be handled by Spring's
+ * {@link CqlTemplate}.
*
* Allows for returning a result object created within the callback, i.e. a domain object or a collection of domain
* objects. Note that there's special support for single step actions: see
* {@link CqlTemplate#queryForObject(String, Class, Object...)} etc. A thrown RuntimeException is treated as
* application exception, it gets propagated to the caller of the template.
*
+ * @param session active Cassandra session, must not be {@literal null}.
* @param preparedStatement the {@link PreparedStatement}, must not be {@literal null}.
* @return a result object publisher.
* @throws DriverException if thrown by a session method, to be auto-converted to a DataAccessException.
@@ -54,6 +57,7 @@ public interface PreparedStatementCallback {
* @see CqlTemplate#queryForObject(String, Class, Object...)
* @see CqlTemplate#queryForList(String, Object...)
*/
- T doInPreparedStatement(PreparedStatement preparedStatement) throws DriverException, DataAccessException;
+ T doInPreparedStatement(Session session, PreparedStatement preparedStatement)
+ throws DriverException, DataAccessException;
}
diff --git a/spring-cql/src/main/java/org/springframework/cassandra/core/session/DefaultSessionFactory.java b/spring-cql/src/main/java/org/springframework/cassandra/core/session/DefaultSessionFactory.java
new file mode 100644
index 000000000..68e8e1f87
--- /dev/null
+++ b/spring-cql/src/main/java/org/springframework/cassandra/core/session/DefaultSessionFactory.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2017 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
+ *
+ * http://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.cassandra.core.session;
+
+import org.springframework.util.Assert;
+
+import com.datastax.driver.core.Session;
+
+/**
+ * Default {@link SessionFactory} implementation.
+ *
+ * This class uses a singleton {@link Session} and returns the same instances.
+ *
+ * @author Mark Paluch
+ * @since 2.0
+ * @see #getSession()
+ * @see Session
+ */
+public class DefaultSessionFactory implements SessionFactory {
+
+ private final Session session;
+
+ /**
+ * Constructs a new {@link DefaultSessionFactory} given {@link Session}.
+ *
+ * @param session the {@link Session} to be used in {@link #getSession()}.
+ */
+ public DefaultSessionFactory(Session session) {
+
+ Assert.notNull(session, "Session must not be null");
+
+ this.session = session;
+ }
+
+ @Override
+ public Session getSession() {
+ return session;
+ }
+}
diff --git a/spring-cql/src/main/java/org/springframework/cassandra/core/session/SessionFactory.java b/spring-cql/src/main/java/org/springframework/cassandra/core/session/SessionFactory.java
new file mode 100644
index 000000000..14f029f77
--- /dev/null
+++ b/spring-cql/src/main/java/org/springframework/cassandra/core/session/SessionFactory.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2017 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
+ *
+ * http://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.cassandra.core.session;
+
+import com.datastax.driver.core.Session;
+
+/**
+ * A factory for Apache Cassandra sessions.
+ *
+ * An alternative to the {@link com.datastax.driver.core.Cluster} facility, a {@link SessionFactory} object is the
+ * preferred means of getting a connection. The {@link SessionFactory} interface is implemented by a {@link Session}
+ * provider.
+ *
+ * A {@link SessionFactory} object can have properties that can be modified when necessary. For example, if the
+ * {@link Session} 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
+ * @since 2.0
+ */
+public interface SessionFactory {
+
+ /**
+ * Attempts to establish a {@link Session} with the connection infrastructure that this {@link SessionFactory} object
+ * represents.
+ *
+ * @return a {@link Session} to Apache Cassandra.
+ */
+ Session getSession();
+}
diff --git a/spring-cql/src/main/java/org/springframework/cassandra/core/session/package-info.java b/spring-cql/src/main/java/org/springframework/cassandra/core/session/package-info.java
new file mode 100644
index 000000000..268a7666b
--- /dev/null
+++ b/spring-cql/src/main/java/org/springframework/cassandra/core/session/package-info.java
@@ -0,0 +1,7 @@
+/**
+ * Provides utility classes for simple {@link com.datastax.driver.core.Session} access and various simple DataSource
+ * implementations.
+ *
+ * @author Mark Paluch
+ */
+package org.springframework.cassandra.core.session;
diff --git a/spring-cql/src/main/java/org/springframework/cassandra/support/CassandraAccessor.java b/spring-cql/src/main/java/org/springframework/cassandra/support/CassandraAccessor.java
index 3ed3ec910..595aa4b9c 100644
--- a/spring-cql/src/main/java/org/springframework/cassandra/support/CassandraAccessor.java
+++ b/spring-cql/src/main/java/org/springframework/cassandra/support/CassandraAccessor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2016 the original author or authors.
+ * Copyright 2013-2017 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.
@@ -18,15 +18,6 @@ package org.springframework.cassandra.support;
import java.util.Map;
import java.util.stream.StreamSupport;
-import com.datastax.driver.core.ConsistencyLevel;
-import com.datastax.driver.core.PreparedStatement;
-import com.datastax.driver.core.ResultSet;
-import com.datastax.driver.core.Session;
-import com.datastax.driver.core.Statement;
-import com.datastax.driver.core.exceptions.DriverException;
-import com.datastax.driver.core.policies.RetryPolicy;
-import com.datastax.driver.core.querybuilder.QueryBuilder;
-
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
@@ -39,15 +30,26 @@ import org.springframework.cassandra.core.RowCallbackHandler;
import org.springframework.cassandra.core.RowMapper;
import org.springframework.cassandra.core.RowMapperResultSetExtractor;
import org.springframework.cassandra.core.SingleColumnRowMapper;
+import org.springframework.cassandra.core.session.DefaultSessionFactory;
+import org.springframework.cassandra.core.session.SessionFactory;
import org.springframework.dao.DataAccessException;
import org.springframework.util.Assert;
+import com.datastax.driver.core.ConsistencyLevel;
+import com.datastax.driver.core.PreparedStatement;
+import com.datastax.driver.core.ResultSet;
+import com.datastax.driver.core.Session;
+import com.datastax.driver.core.Statement;
+import com.datastax.driver.core.exceptions.DriverException;
+import com.datastax.driver.core.policies.RetryPolicy;
+import com.datastax.driver.core.querybuilder.QueryBuilder;
+
/**
- * {@link CassandraAccessor} provides access to a Cassandra {@link Session} and the {@link CassandraExceptionTranslator}
- * .
+ * {@link CassandraAccessor} provides access to a Cassandra {@link SessionFactory} and the
+ * {@link CassandraExceptionTranslator}.
*
* Classes providing a higher abstraction level usually extend {@link CassandraAccessor} to provide a richer set of
- * functionality on top of a {@link Session}.
+ * functionality on top of a {@link SessionFactory} using {@link Session}.
*
* @author David Webb
* @author Mark Paluch
@@ -84,29 +86,20 @@ public class CassandraAccessor implements InitializingBean {
*/
private com.datastax.driver.core.policies.RetryPolicy retryPolicy;
- private Session session;
+ private SessionFactory sessionFactory;
/**
* Ensures the Cassandra {@link Session} and exception translator has been propertly set.
*/
@Override
public void afterPropertiesSet() {
- Assert.state(session != null, "Session must not be null");
- }
-
- /* (non-Javadoc) */
- @SuppressWarnings("unused")
- protected void logDebug(String logMessage, Object... array) {
- if (logger.isDebugEnabled()) {
- logger.debug(logMessage, array);
- }
+ Assert.state(sessionFactory != null, "SessionFactory must not be null");
}
/**
- * Set the consistency level for this template. Consistency level defines the number of nodes
- * involved into query processing. Relaxed consistency level settings use fewer nodes but eventual consistency is more
- * likely to occur while a higher consistency level involves more nodes to obtain results with a higher consistency
- * guarantee.
+ * Set the consistency level for this template. Consistency level defines the number of nodes involved into query
+ * processing. Relaxed consistency level settings use fewer nodes but eventual consistency is more likely to occur
+ * while a higher consistency level involves more nodes to obtain results with a higher consistency guarantee.
*
* @see Statement#setConsistencyLevel(ConsistencyLevel)
* @see RetryPolicy
@@ -147,10 +140,10 @@ public class CassandraAccessor implements InitializingBean {
}
/**
- * Set the fetch size for this template. This is important for processing large result sets: Setting this
- * higher than the default value will increase processing speed at the cost of memory consumption; setting this lower
- * can avoid transferring row data that will never be read by the application. Default is -1, indicating to use the
- * CQL driver's default configuration (i.e. to not pass a specific fetch size setting on to the driver).
+ * Set the fetch size for this template. This is important for processing large result sets: Setting this higher than
+ * the default value will increase processing speed at the cost of memory consumption; setting this lower can avoid
+ * transferring row data that will never be read by the application. Default is -1, indicating to use the CQL driver's
+ * default configuration (i.e. to not pass a specific fetch size setting on to the driver).
*
* @see Statement#setFetchSize(int)
*/
@@ -166,8 +159,7 @@ public class CassandraAccessor implements InitializingBean {
}
/**
- * Set the retry policy for this template. This is important for defining behavior when a request
- * fails.
+ * Set the retry policy for this template. This is important for defining behavior when a request fails.
*
* @see Statement#setRetryPolicy(RetryPolicy)
* @see RetryPolicy
@@ -184,25 +176,60 @@ public class CassandraAccessor implements InitializingBean {
}
/**
- * Sets the Cassandra {@link Session} used by this template to perform Cassandra data access operations.
+ * Sets the Cassandra {@link Session} used by this template to perform Cassandra data access operations. The
+ * {@code session} will replace the current {@link #getSessionFactory()} with {@link DefaultSessionFactory}.
*
- * @param session Cassandra {@link Session} used by this template. Must not be{@literal null}.
+ * @param session Cassandra {@link Session} used by this template, must not be{@literal null}.
* @see com.datastax.driver.core.Session
+ * @see DefaultSessionFactory
*/
public void setSession(Session session) {
+
Assert.notNull(session, "Session must not be null");
- this.session = session;
+
+ setSessionFactory(new DefaultSessionFactory(session));
}
/**
- * Returns the Cassandra {@link Session} used by this template to perform Cassandra data access operations.
+ * Returns the Cassandra {@link Session} from {@link SessionFactory} used by this template to perform Cassandra data
+ * access operations.
*
* @return the Cassandra {@link Session} used by this template.
* @see com.datastax.driver.core.Session
+ * @deprecated since 2.0. This class uses a {@link SessionFactory} to dispatch CQL calls amongst different
+ * {@link Session}s during its lifecycle.
*/
+ @Deprecated
public Session getSession() {
- Assert.state(this.session != null, "Session was not properly initialized");
- return this.session;
+
+ Assert.state(getSessionFactory() != null, "SessionFactory was not properly initialized");
+
+ return getSessionFactory().getSession();
+ }
+
+ /**
+ * Sets the Cassandra {@link SessionFactory} used by this template to perform Cassandra data access operations.
+ *
+ * @param sessionFactory Cassandra {@link Session} used by this template. Must not be{@literal null}.
+ * @since 2.0
+ * @see com.datastax.driver.core.Session
+ */
+ public void setSessionFactory(SessionFactory sessionFactory) {
+
+ Assert.notNull(sessionFactory, "SessionFactory must not be null");
+
+ this.sessionFactory = sessionFactory;
+ }
+
+ /**
+ * Returns the Cassandra {@link SessionFactory} used by this template to perform Cassandra data access operations.
+ *
+ * @return the Cassandra {@link SessionFactory} used by this template.
+ * @since 2.0
+ * @see SessionFactory
+ */
+ public SessionFactory getSessionFactory() {
+ return this.sessionFactory;
}
/**
@@ -274,8 +301,8 @@ public class CassandraAccessor implements InitializingBean {
}
/**
- * Constructs a new instance of the {@link ResultSetExtractor} initialized with and adapting
- * the given {@link RowCallbackHandler}.
+ * Constructs a new instance of the {@link ResultSetExtractor} initialized with and adapting the given
+ * {@link RowCallbackHandler}.
*
* @param rowCallbackHandler {@link RowCallbackHandler} to adapt as a {@link ResultSetExtractor}.
* @return a {@link ResultSetExtractor} implementation adapting an instance of the {@link RowCallbackHandler}.
@@ -288,8 +315,8 @@ public class CassandraAccessor implements InitializingBean {
}
/**
- * Constructs a new instance of the {@link ResultSetExtractor} initialized with and adapting
- * the given {@link RowMapper}.
+ * Constructs a new instance of the {@link ResultSetExtractor} initialized with and adapting the given
+ * {@link RowMapper}.
*
* @param rowMapper {@link RowMapper} to adapt as a {@link ResultSetExtractor}.
* @return a {@link ResultSetExtractor} implementation adapting an instance of the {@link RowMapper}.
@@ -302,8 +329,8 @@ public class CassandraAccessor implements InitializingBean {
}
/**
- * Constructs a new instance of the {@link ResultSetExtractor} initialized with and adapting
- * the given {@link RowMapper}.
+ * Constructs a new instance of the {@link ResultSetExtractor} initialized with and adapting the given
+ * {@link RowMapper}.
*
* @param rowMapper {@link RowMapper} to adapt as a {@link ResultSetExtractor}.
* @param rowsExpected number of expected rows in the {@link ResultSet}.
@@ -348,6 +375,12 @@ public class CassandraAccessor implements InitializingBean {
return (cqlProvider instanceof CqlProvider ? ((CqlProvider) cqlProvider).getCql() : null);
}
+ protected void logDebug(String logMessage, Object... array) {
+ if (logger.isDebugEnabled()) {
+ logger.debug(logMessage, array);
+ }
+ }
+
/**
* Translate the given {@link DriverException} into a generic {@link DataAccessException}.
*
diff --git a/spring-cql/src/test/java/org/springframework/cassandra/core/AsyncCqlTemplateUnitTests.java b/spring-cql/src/test/java/org/springframework/cassandra/core/AsyncCqlTemplateUnitTests.java
index b0f18b4bb..2229a6295 100644
--- a/spring-cql/src/test/java/org/springframework/cassandra/core/AsyncCqlTemplateUnitTests.java
+++ b/spring-cql/src/test/java/org/springframework/cassandra/core/AsyncCqlTemplateUnitTests.java
@@ -481,8 +481,7 @@ public class AsyncCqlTemplateUnitTests {
doTestStrings(null, null, null, asyncCqlTemplate -> {
ListenableFuture futureOfFuture = asyncCqlTemplate.execute("SELECT * from USERS",
- (PreparedStatementCallback) (ps) -> asyncCqlTemplate.getSession()
- .executeAsync(ps.bind("A")));
+ (session, ps) -> session.executeAsync(ps.bind("A")));
try {
assertThat(getUninterruptibly(futureOfFuture).get()).hasSize(3);
@@ -515,7 +514,7 @@ public class AsyncCqlTemplateUnitTests {
try {
template.execute(session -> {
throw new NoHostAvailableException(Collections.emptyMap());
- }, (ps) -> session.executeAsync(boundStatement));
+ }, (session, ps) -> session.executeAsync(boundStatement));
fail("Missing CassandraConnectionFailureException");
} catch (CassandraConnectionFailureException e) {
assertThat(e).hasMessageContaining("tried for query");
@@ -523,7 +522,7 @@ public class AsyncCqlTemplateUnitTests {
ListenableFuture future = template.execute(
session -> AsyncResult.forExecutionException(new NoHostAvailableException(Collections.emptyMap())),
- (ps) -> session.executeAsync(boundStatement));
+ (session, ps) -> session.executeAsync(boundStatement));
try {
future.get();
@@ -542,7 +541,7 @@ public class AsyncCqlTemplateUnitTests {
when(resultSet.wasApplied()).thenReturn(true);
ListenableFuture future = template.execute(session -> new AsyncResult<>(preparedStatement),
- (ps) -> {
+ (session, ps) -> {
throw new NoHostAvailableException(Collections.emptyMap());
});
diff --git a/spring-cql/src/test/java/org/springframework/cassandra/core/CqlTemplateUnitTests.java b/spring-cql/src/test/java/org/springframework/cassandra/core/CqlTemplateUnitTests.java
index a0dc5f408..431ea90b4 100644
--- a/spring-cql/src/test/java/org/springframework/cassandra/core/CqlTemplateUnitTests.java
+++ b/spring-cql/src/test/java/org/springframework/cassandra/core/CqlTemplateUnitTests.java
@@ -442,7 +442,7 @@ public class CqlTemplateUnitTests {
doTestStrings(null, null, null, cqlTemplate -> {
ResultSet resultSet = cqlTemplate.execute("SELECT * from USERS",
- (PreparedStatementCallback) (ps) -> cqlTemplate.getSession().execute(ps.bind("A")));
+ (session, ps) -> session.execute(ps.bind("A")));
try {
assertThat(resultSet).hasSize(3);
@@ -475,7 +475,7 @@ public class CqlTemplateUnitTests {
try {
template.execute(session -> {
throw new NoHostAvailableException(Collections.emptyMap());
- }, (ps) -> session.execute(boundStatement));
+ }, (session, ps) -> session.execute(boundStatement));
fail("Missing CassandraConnectionFailureException");
} catch (CassandraConnectionFailureException e) {
@@ -490,7 +490,7 @@ public class CqlTemplateUnitTests {
when(resultSet.wasApplied()).thenReturn(true);
try {
- template.execute(session -> preparedStatement, (ps) -> {
+ template.execute(session -> preparedStatement, (session, ps) -> {
throw new NoHostAvailableException(Collections.emptyMap());
});
diff --git a/spring-cql/src/test/java/org/springframework/cassandra/support/CassandraAccessorUnitTests.java b/spring-cql/src/test/java/org/springframework/cassandra/support/CassandraAccessorUnitTests.java
index 0a66af5a1..8c02e7f5f 100755
--- a/spring-cql/src/test/java/org/springframework/cassandra/support/CassandraAccessorUnitTests.java
+++ b/spring-cql/src/test/java/org/springframework/cassandra/support/CassandraAccessorUnitTests.java
@@ -49,14 +49,14 @@ public class CassandraAccessorUnitTests {
cassandraAccessor = new CassandraAccessor();
}
- @Test // DATACASS-286
+ @Test // DATACASS-286, DATACASS-330
public void afterPropertiesSetWithUnitializedSessionThrowsIllegalStateException() {
try {
cassandraAccessor.afterPropertiesSet();
fail("Missing IllegalStateException");
} catch (IllegalStateException e) {
- assertThat(e).hasMessageContaining("Session must not be null");
+ assertThat(e).hasMessageContaining("SessionFactory must not be null");
}
}
@@ -101,14 +101,14 @@ public class CassandraAccessorUnitTests {
}
}
- @Test // DATACASS-286
+ @Test // DATACASS-286, DATACASS-330
public void getUninitializedSessionThrowsIllegalStateException() {
try {
cassandraAccessor.getSession();
fail("Missing IllegalStateException");
} catch (IllegalStateException e) {
- assertThat(e).hasMessageContaining("Session was not properly initialized");
+ assertThat(e).hasMessageContaining("SessionFactory was not properly initialized");
}
}
}
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 131bbc834..f9f11ccf1 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
@@ -28,6 +28,8 @@ import org.springframework.cassandra.core.GuavaListenableFutureAdapter;
import org.springframework.cassandra.core.QueryOptions;
import org.springframework.cassandra.core.WriteOptions;
import org.springframework.cassandra.core.cql.CqlIdentifier;
+import org.springframework.cassandra.core.session.DefaultSessionFactory;
+import org.springframework.cassandra.core.session.SessionFactory;
import org.springframework.cassandra.core.support.CQLExceptionTranslator;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.InvalidDataAccessApiUsageException;
@@ -100,17 +102,21 @@ public class AsyncCassandraTemplate implements AsyncCassandraOperations {
* @see Session
*/
public AsyncCassandraTemplate(Session session, CassandraConverter converter) {
+ this(new DefaultSessionFactory(session), converter);
+ }
- Assert.notNull(session, "Session must not be null");
- Assert.notNull(converter, "CassandraConverter must not be null");
-
- this.converter = converter;
- this.mappingContext = converter.getMappingContext();
-
- AsyncCqlTemplate asyncCqlTemplate = new AsyncCqlTemplate(session);
-
- this.cqlOperations = asyncCqlTemplate;
- this.exceptionTranslator = asyncCqlTemplate.getExceptionTranslator();
+ /**
+ * Creates an instance of {@link AsyncCassandraTemplate} initialized with the given {@link SessionFactory} and
+ * {@link CassandraConverter}.
+ *
+ * @param sessionFactory {@link SessionFactory} used to interact with Cassandra; must not be {@literal null}.
+ * @param converter {@link CassandraConverter} used to convert between Java and Cassandra types; must not be
+ * {@literal null}.
+ * @see CassandraConverter
+ * @see Session
+ */
+ public AsyncCassandraTemplate(SessionFactory sessionFactory, CassandraConverter converter) {
+ this(new AsyncCqlTemplate(sessionFactory), converter);
}
/**
@@ -226,7 +232,9 @@ public class AsyncCassandraTemplate implements AsyncCassandraOperations {
Assert.notNull(entityConsumer, "Entity Consumer must not be empty");
Assert.notNull(entityClass, "Entity type must not be null");
- return cqlOperations.query(statement, (row) -> { entityConsumer.accept(converter.read(entityClass, row)); });
+ return cqlOperations.query(statement, (row) -> {
+ entityConsumer.accept(converter.read(entityClass, row));
+ });
}
/*
@@ -237,7 +245,7 @@ public class AsyncCassandraTemplate implements AsyncCassandraOperations {
public ListenableFuture selectOne(Statement statement, Class entityClass) {
return new MappingListenableFutureAdapter<>(select(statement, entityClass),
- list -> list.isEmpty() ? null : list.get(0));
+ list -> list.isEmpty() ? null : list.get(0));
}
// -------------------------------------------------------------------------
@@ -275,7 +283,7 @@ public class AsyncCassandraTemplate implements AsyncCassandraOperations {
converter.write(id, select.where(), entity);
return new MappingListenableFutureAdapter<>(cqlOperations.queryForResultSet(select),
- resultSet -> resultSet.iterator().hasNext());
+ resultSet -> resultSet.iterator().hasNext());
}
/*
@@ -446,10 +454,10 @@ public class AsyncCassandraTemplate implements AsyncCassandraOperations {
@Override
public ListenableFuture doInSession(Session session) throws DriverException, DataAccessException {
- return new GuavaListenableFutureAdapter<>(session.executeAsync(statement), e -> (e instanceof DriverException
- ? exceptionTranslator.translate("AsyncStatementCallback", getCql(), (DriverException) e)
- : exceptionTranslator.translateExceptionIfPossible(e))
- );
+ return new GuavaListenableFutureAdapter<>(session.executeAsync(statement),
+ e -> (e instanceof DriverException
+ ? exceptionTranslator.translate("AsyncStatementCallback", getCql(), (DriverException) e)
+ : exceptionTranslator.translateExceptionIfPossible(e)));
}
@Override
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 a1c3c9971..76f0c0907 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2016 the original author or authors.
+ * Copyright 2016-2017 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.
@@ -19,6 +19,25 @@ import java.util.List;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
+import org.springframework.cassandra.core.CqlOperations;
+import org.springframework.cassandra.core.CqlProvider;
+import org.springframework.cassandra.core.CqlTemplate;
+import org.springframework.cassandra.core.QueryOptions;
+import org.springframework.cassandra.core.SessionCallback;
+import org.springframework.cassandra.core.WriteOptions;
+import org.springframework.cassandra.core.cql.CqlIdentifier;
+import org.springframework.cassandra.core.session.DefaultSessionFactory;
+import org.springframework.cassandra.core.session.SessionFactory;
+import org.springframework.cassandra.core.util.CollectionUtils;
+import org.springframework.dao.DataAccessException;
+import org.springframework.dao.InvalidDataAccessApiUsageException;
+import org.springframework.data.cassandra.convert.CassandraConverter;
+import org.springframework.data.cassandra.convert.MappingCassandraConverter;
+import org.springframework.data.cassandra.mapping.CassandraMappingContext;
+import org.springframework.data.cassandra.mapping.CassandraPersistentEntity;
+import org.springframework.util.Assert;
+import org.springframework.util.ClassUtils;
+
import com.datastax.driver.core.ResultSet;
import com.datastax.driver.core.Session;
import com.datastax.driver.core.SimpleStatement;
@@ -31,23 +50,6 @@ import com.datastax.driver.core.querybuilder.Select;
import com.datastax.driver.core.querybuilder.Truncate;
import com.datastax.driver.core.querybuilder.Update;
-import org.springframework.cassandra.core.CqlOperations;
-import org.springframework.cassandra.core.CqlProvider;
-import org.springframework.cassandra.core.CqlTemplate;
-import org.springframework.cassandra.core.QueryOptions;
-import org.springframework.cassandra.core.SessionCallback;
-import org.springframework.cassandra.core.WriteOptions;
-import org.springframework.cassandra.core.cql.CqlIdentifier;
-import org.springframework.cassandra.core.util.CollectionUtils;
-import org.springframework.dao.DataAccessException;
-import org.springframework.dao.InvalidDataAccessApiUsageException;
-import org.springframework.data.cassandra.convert.CassandraConverter;
-import org.springframework.data.cassandra.convert.MappingCassandraConverter;
-import org.springframework.data.cassandra.mapping.CassandraMappingContext;
-import org.springframework.data.cassandra.mapping.CassandraPersistentEntity;
-import org.springframework.util.Assert;
-import org.springframework.util.ClassUtils;
-
/**
* Primary implementation of {@link CassandraOperations}. It simplifies the use of Cassandra usage and helps to avoid
* common errors. It executes core Cassandra workflow. This class executes CQL queries or updates, initiating iteration
@@ -93,13 +95,21 @@ public class CassandraTemplate implements CassandraOperations {
* @see Session
*/
public CassandraTemplate(Session session, CassandraConverter converter) {
+ this(new DefaultSessionFactory(session), converter);
+ }
- Assert.notNull(session, "Session must not be null");
- Assert.notNull(converter, "CassandraConverter must not be null");
-
- this.converter = converter;
- this.mappingContext = converter.getMappingContext();
- this.cqlOperations = new CqlTemplate(session);
+ /**
+ * Creates an instance of {@link CassandraTemplate} initialized with the given {@link SessionFactory} and
+ * {@link CassandraConverter}.
+ *
+ * @param sessionFactory {@link SessionFactory} used to interact with Cassandra; must not be {@literal null}.
+ * @param converter {@link CassandraConverter} used to convert between Java and Cassandra types; must not be
+ * {@literal null}.
+ * @see CassandraConverter
+ * @see SessionFactory
+ */
+ public CassandraTemplate(SessionFactory sessionFactory, CassandraConverter converter) {
+ this(new CqlTemplate(sessionFactory), converter);
}
/**
@@ -311,8 +321,7 @@ public class CassandraTemplate implements CassandraOperations {
Assert.notNull(entity, "Entity must not be null");
- Insert insert = QueryUtils.createInsertQuery(getTableName(entity.getClass()).toCql(),
- entity, options, converter);
+ Insert insert = QueryUtils.createInsertQuery(getTableName(entity.getClass()).toCql(), entity, options, converter);
return cqlOperations.execute(new StatementCallback<>(insert, entity));
}
@@ -335,8 +344,7 @@ public class CassandraTemplate implements CassandraOperations {
Assert.notNull(entity, "Entity must not be null");
- Update update = QueryUtils.createUpdateQuery(getTableName(entity.getClass()).toCql(),
- entity, options, converter);
+ Update update = QueryUtils.createUpdateQuery(getTableName(entity.getClass()).toCql(), entity, options, converter);
return cqlOperations.execute(new StatementCallback<>(update, entity));
}
@@ -359,8 +367,7 @@ public class CassandraTemplate implements CassandraOperations {
Assert.notNull(entity, "Entity must not be null");
- Delete delete = QueryUtils.createDeleteQuery(getTableName(entity.getClass()).toCql(),
- entity, options, converter);
+ Delete delete = QueryUtils.createDeleteQuery(getTableName(entity.getClass()).toCql(), entity, options, converter);
return cqlOperations.execute(new StatementCallback<>(delete, entity));
}
@@ -428,7 +435,7 @@ public class CassandraTemplate implements CassandraOperations {
if (entity == null) {
throw new InvalidDataAccessApiUsageException(
- String.format("No Persistent Entity information found for the class [%s]", entityClass.getName()));
+ String.format("No Persistent Entity information found for the class [%s]", entityClass.getName()));
}
return entity;