Uploaded image for project: 'Spring Data for Apache Cassandra'
  1. Spring Data for Apache Cassandra
  2. DATACASS-591

AsyncCqlTemplate Cached Prepared Statements



    • Type: Bug
    • Status: Open
    • Priority: Major
    • Resolution: Unresolved
    • Affects Version/s: 2.0.9 (Kay SR9)
    • Fix Version/s: None
    • Component/s: Core
    • Labels:
    • Last commented by a User:


      I upgraded from spring data cassandra 1.5.x to 2.0.9 and noticed when using the AsyncCqlTemplate that there is no default implementations to cache prepared statements like there is for CqlTemplate.


      Without the prepared statements I get a lot of warnings from cassandra as follows:

      WARN com.datastax.driver.core.Cluster - Re-preparing already prepared query is generally an anti-pattern and will likely affect performance. Consider preparing the statement only once. Query='...`

      Even though this is asynchronous operation I think it makes sense to provide a cached prepared statement. I was able to fix this by doing the following...which is similar in nature to `org.springframework.data.cassandra.core.cql.support.MapPreparedStatementCache`


      If you believe this is the correct approach I can clean this up and put a PR in. Please let me know.

      public class AsyncCachedPreparedStatementCreator implements AsyncPreparedStatementCreator {
          private final String cql;
          private final Map<CacheKey, com.google.common.util.concurrent.ListenableFuture<PreparedStatement>> cache;
          AsyncCachedPreparedStatementCreator(String cql,
                                              Map<CacheKey, com.google.common.util.concurrent.ListenableFuture<PreparedStatement>> cache) {
              Assert.notNull(cache, "cql must not be null");
              Assert.notNull(cache, "Cache must not be null");
              this.cql = cql;
              this.cache = cache;
          public ListenableFuture<PreparedStatement> createPreparedStatement(Session session) throws DriverException {
              CacheKey cacheKey = new CacheKey(session, cql);
              com.google.common.util.concurrent.ListenableFuture<PreparedStatement> future = cache.computeIfAbsent(cacheKey,
                                                                                                                   k -> session.prepareAsync(cql));
              return new GuavaListenableFutureAdapter<>(future, new CassandraExceptionTranslator());
          private class CacheKey {
              final Cluster cluster;
              final String  keyspace;
              final String  cql;
              CacheKey(Session session, String cql) {
                  this.cluster = session.getCluster();
                  this.keyspace = session.getLoggedKeyspace();
                  this.cql = cql;
              public boolean equals(final Object obj) {
                  if (!(obj instanceof CacheKey)) {
                      return false;
                  if (obj == this) {
                      return true;
                  CacheKey rhs = (CacheKey) obj;
                  return new EqualsBuilder()
                      .append(cluster, rhs.cluster)
                      .append(keyspace, rhs.keyspace)
                      .append(cql, rhs.cql)
              public int hashCode() {
                  return new HashCodeBuilder()


          Issue Links



              mp911de Mark Paluch
              mbazos Michael Bazos
              Last updater:
              Mark Paluch
              0 Vote for this issue
              1 Start watching this issue


                Days since last comment:
                2 years, 4 weeks, 5 days ago