Repository: ignite
Updated Branches:
  refs/heads/master 1bc605866 -> bcbe8cc44


IGNITE-3313 Make table name optional in Cassandra persistence descriptor. - 
Fixes #1086.

Signed-off-by: AKuznetsov <akuznet...@gridgain.com>


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/f0e4e06a
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/f0e4e06a
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/f0e4e06a

Branch: refs/heads/master
Commit: f0e4e06af3734addf64c05ba6a73331db2031c58
Parents: 1bc6058
Author: Igor <irud...@gmail.com>
Authored: Tue Sep 20 21:55:00 2016 +0700
Committer: AKuznetsov <akuznet...@gridgain.com>
Committed: Tue Sep 20 21:55:00 2016 +0700

----------------------------------------------------------------------
 .../store/cassandra/CassandraCacheStore.java    |  71 +++++++-
 .../KeyValuePersistenceSettings.java            |  32 ++--
 .../persistence/PersistenceController.java      | 103 ++++++-----
 .../session/BatchExecutionAssistant.java        |   7 +
 .../cassandra/session/CassandraSessionImpl.java |  64 ++++---
 .../cassandra/session/ExecutionAssistant.java   |  13 +-
 .../store/cassandra/utils/DDLGenerator.java     |   6 +-
 .../tests/CassandraDirectPersistenceTest.java   |  17 ++
 .../apache/ignite/tests/DDLGeneratorTest.java   |  24 ++-
 .../ignite/tests/IgnitePersistentStoreTest.java |  15 ++
 .../LoadTestsCassandraArtifactsCreator.java     |   4 +-
 .../tests/persistence/pojo/ignite-config.xml    |  18 ++
 .../persistence/pojo/persistence-settings-4.xml | 175 +++++++++++++++++++
 13 files changed, 435 insertions(+), 114 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/f0e4e06a/modules/cassandra/store/src/main/java/org/apache/ignite/cache/store/cassandra/CassandraCacheStore.java
----------------------------------------------------------------------
diff --git 
a/modules/cassandra/store/src/main/java/org/apache/ignite/cache/store/cassandra/CassandraCacheStore.java
 
b/modules/cassandra/store/src/main/java/org/apache/ignite/cache/store/cassandra/CassandraCacheStore.java
index 9ba3a75..52ff3c4 100644
--- 
a/modules/cassandra/store/src/main/java/org/apache/ignite/cache/store/cassandra/CassandraCacheStore.java
+++ 
b/modules/cassandra/store/src/main/java/org/apache/ignite/cache/store/cassandra/CassandraCacheStore.java
@@ -145,26 +145,37 @@ public class CassandraCacheStore<K, V> implements 
CacheStore<K, V> {
 
         try {
             return ses.execute(new ExecutionAssistant<V>() {
+                /** {@inheritDoc} */
                 @Override public boolean tableExistenceRequired() {
                     return false;
                 }
 
+                /** {@inheritDoc} */
+                @Override public String getTable() {
+                    return cassandraTable();
+                }
+
+                /** {@inheritDoc} */
                 @Override public String getStatement() {
-                    return controller.getLoadStatement(false);
+                    return controller.getLoadStatement(cassandraTable(), 
false);
                 }
 
+                /** {@inheritDoc} */
                 @Override public BoundStatement 
bindStatement(PreparedStatement statement) {
                     return controller.bindKey(statement, key);
                 }
 
+                /** {@inheritDoc} */
                 @Override public KeyValuePersistenceSettings 
getPersistenceSettings() {
                     return controller.getPersistenceSettings();
                 }
 
+                /** {@inheritDoc} */
                 @Override public String operationName() {
                     return "READ";
                 }
 
+                /** {@inheritDoc} */
                 @Override public V process(Row row) {
                     return row == null ? null : 
(V)controller.buildValueObject(row);
                 }
@@ -188,8 +199,13 @@ public class CassandraCacheStore<K, V> implements 
CacheStore<K, V> {
                 private Map<K, V> data = new HashMap<>();
 
                 /** {@inheritDoc} */
+                @Override public String getTable() {
+                    return cassandraTable();
+                }
+
+                /** {@inheritDoc} */
                 @Override public String getStatement() {
-                    return controller.getLoadStatement(true);
+                    return controller.getLoadStatement(cassandraTable(), true);
                 }
 
                 /** {@inheritDoc} */
@@ -232,26 +248,37 @@ public class CassandraCacheStore<K, V> implements 
CacheStore<K, V> {
 
         try {
             ses.execute(new ExecutionAssistant<Void>() {
+                /** {@inheritDoc} */
                 @Override public boolean tableExistenceRequired() {
                     return true;
                 }
 
+                /** {@inheritDoc} */
+                @Override public String getTable() {
+                    return cassandraTable();
+                }
+
+                /** {@inheritDoc} */
                 @Override public String getStatement() {
-                    return controller.getWriteStatement();
+                    return controller.getWriteStatement(cassandraTable());
                 }
 
+                /** {@inheritDoc} */
                 @Override public BoundStatement 
bindStatement(PreparedStatement statement) {
                     return controller.bindKeyValue(statement, entry.getKey(), 
entry.getValue());
                 }
 
+                /** {@inheritDoc} */
                 @Override public KeyValuePersistenceSettings 
getPersistenceSettings() {
                     return controller.getPersistenceSettings();
                 }
 
+                /** {@inheritDoc} */
                 @Override public String operationName() {
                     return "WRITE";
                 }
 
+                /** {@inheritDoc} */
                 @Override public Void process(Row row) {
                     return null;
                 }
@@ -272,8 +299,13 @@ public class CassandraCacheStore<K, V> implements 
CacheStore<K, V> {
         try {
             ses.execute(new GenericBatchExecutionAssistant<Void, Cache.Entry<? 
extends K, ? extends V>>() {
                 /** {@inheritDoc} */
+                @Override public String getTable() {
+                    return cassandraTable();
+                }
+
+                /** {@inheritDoc} */
                 @Override public String getStatement() {
-                    return controller.getWriteStatement();
+                    return controller.getWriteStatement(cassandraTable());
                 }
 
                 /** {@inheritDoc} */
@@ -312,27 +344,38 @@ public class CassandraCacheStore<K, V> implements 
CacheStore<K, V> {
 
         try {
             ses.execute(new ExecutionAssistant<Void>() {
+                /** {@inheritDoc} */
                 @Override public boolean tableExistenceRequired() {
                     return false;
                 }
 
+                /** {@inheritDoc} */
+                @Override public String getTable() {
+                    return cassandraTable();
+                }
+
+                /** {@inheritDoc} */
                 @Override public String getStatement() {
-                    return controller.getDeleteStatement();
+                    return controller.getDeleteStatement(cassandraTable());
                 }
 
+                /** {@inheritDoc} */
                 @Override public BoundStatement 
bindStatement(PreparedStatement statement) {
                     return controller.bindKey(statement, key);
                 }
 
 
+                /** {@inheritDoc} */
                 @Override public KeyValuePersistenceSettings 
getPersistenceSettings() {
                     return controller.getPersistenceSettings();
                 }
 
+                /** {@inheritDoc} */
                 @Override public String operationName() {
                     return "DELETE";
                 }
 
+                /** {@inheritDoc} */
                 @Override public Void process(Row row) {
                     return null;
                 }
@@ -353,8 +396,13 @@ public class CassandraCacheStore<K, V> implements 
CacheStore<K, V> {
         try {
             ses.execute(new GenericBatchExecutionAssistant<Void, Object>() {
                 /** {@inheritDoc} */
+                @Override public String getTable() {
+                    return cassandraTable();
+                }
+
+                /** {@inheritDoc} */
                 @Override public String getStatement() {
-                    return controller.getDeleteStatement();
+                    return controller.getDeleteStatement(cassandraTable());
                 }
 
                 /** {@inheritDoc} */
@@ -367,6 +415,7 @@ public class CassandraCacheStore<K, V> implements 
CacheStore<K, V> {
                     return controller.getPersistenceSettings();
                 }
 
+                /** {@inheritDoc} */
                 @Override public String operationName() {
                     return "BULK_DELETE";
                 }
@@ -406,4 +455,14 @@ public class CassandraCacheStore<K, V> implements 
CacheStore<K, V> {
         if (ses != null && (storeSes == null || storeSes.transaction() == 
null))
             U.closeQuiet(ses);
     }
+
+    /**
+     * Returns table name to use for all Cassandra based operations 
(READ/WRITE/DELETE)
+     *
+     * @return table name
+     */
+    private String cassandraTable() {
+        return controller.getPersistenceSettings().getTable() != null ?
+                controller.getPersistenceSettings().getTable() : 
storeSes.cacheName().toLowerCase();
+    }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/f0e4e06a/modules/cassandra/store/src/main/java/org/apache/ignite/cache/store/cassandra/persistence/KeyValuePersistenceSettings.java
----------------------------------------------------------------------
diff --git 
a/modules/cassandra/store/src/main/java/org/apache/ignite/cache/store/cassandra/persistence/KeyValuePersistenceSettings.java
 
b/modules/cassandra/store/src/main/java/org/apache/ignite/cache/store/cassandra/persistence/KeyValuePersistenceSettings.java
index ce8214a..243c2b7 100644
--- 
a/modules/cassandra/store/src/main/java/org/apache/ignite/cache/store/cassandra/persistence/KeyValuePersistenceSettings.java
+++ 
b/modules/cassandra/store/src/main/java/org/apache/ignite/cache/store/cassandra/persistence/KeyValuePersistenceSettings.java
@@ -184,16 +184,6 @@ public class KeyValuePersistenceSettings implements 
Serializable {
     }
 
     /**
-     * Returns full name of Cassandra table to use (including keyspace).
-     *
-     * @return full table name in format "keyspace.table".
-     */
-    public String getTableFullName()
-    {
-        return keyspace + "." + tbl;
-    }
-
-    /**
      * Returns persistence settings for Ignite cache keys.
      *
      * @return keys persistence settings.
@@ -282,9 +272,14 @@ public class KeyValuePersistenceSettings implements 
Serializable {
     /**
      * Returns DDL statement to create Cassandra table.
      *
+     * @param table table name
+     *
      * @return Table DDL statement.
      */
-    public String getTableDDLStatement() {
+    public String getTableDDLStatement(String table) {
+        if (table == null || table.trim().isEmpty())
+            throw new IllegalArgumentException("Table name should be 
specified");
+
         String keyColumnsDDL = keyPersistenceSettings.getTableColumnsDDL();
         String valColumnsDDL = valPersistenceSettings.getTableColumnsDDL(new 
HashSet<>(keyPersistenceSettings.getTableColumns()));
 
@@ -307,7 +302,7 @@ public class KeyValuePersistenceSettings implements 
Serializable {
 
         StringBuilder builder = new StringBuilder();
 
-        builder.append("create table if not exists 
\"").append(keyspace).append("\".\"").append(tbl).append("\"");
+        builder.append("create table if not exists 
\"").append(keyspace).append("\".\"").append(table).append("\"");
         
builder.append("\n(\n").append(colsDDL).append(",\n").append(primaryKeyDDL).append("\n)");
 
         if (!optionsDDL.isEmpty())
@@ -321,9 +316,11 @@ public class KeyValuePersistenceSettings implements 
Serializable {
     /**
      * Returns DDL statements to create Cassandra table secondary indexes.
      *
+     * @param table table name
+     *
      * @return DDL statements to create secondary indexes.
      */
-    public List<String> getIndexDDLStatements() {
+    public List<String> getIndexDDLStatements(String table) {
         List<String> idxDDLs = new LinkedList<>();
 
         Set<String> keyColumns = new 
HashSet<>(keyPersistenceSettings.getTableColumns());
@@ -331,7 +328,7 @@ public class KeyValuePersistenceSettings implements 
Serializable {
 
         for (PojoField field : fields) {
             if (!keyColumns.contains(field.getColumn()) && 
((PojoValueField)field).isIndexed())
-                idxDDLs.add(((PojoValueField)field).getIndexDDL(keyspace, 
tbl));
+                idxDDLs.add(((PojoValueField)field).getIndexDDL(keyspace, 
table));
         }
 
         return idxDDLs;
@@ -419,13 +416,8 @@ public class KeyValuePersistenceSettings implements 
Serializable {
                 "' attribute should be specified");
         }
 
-        if (!root.hasAttribute(TABLE_ATTR)) {
-            throw new IllegalArgumentException("Incorrect persistence settings 
'" + TABLE_ATTR +
-                "' attribute should be specified");
-        }
-
         keyspace = root.getAttribute(KEYSPACE_ATTR).trim();
-        tbl = root.getAttribute(TABLE_ATTR).trim();
+        tbl = root.hasAttribute(TABLE_ATTR) ? 
root.getAttribute(TABLE_ATTR).trim() : null;
 
         if (root.hasAttribute(TTL_ATTR))
             ttl = extractIntAttribute(root, TTL_ATTR);

http://git-wip-us.apache.org/repos/asf/ignite/blob/f0e4e06a/modules/cassandra/store/src/main/java/org/apache/ignite/cache/store/cassandra/persistence/PersistenceController.java
----------------------------------------------------------------------
diff --git 
a/modules/cassandra/store/src/main/java/org/apache/ignite/cache/store/cassandra/persistence/PersistenceController.java
 
b/modules/cassandra/store/src/main/java/org/apache/ignite/cache/store/cassandra/persistence/PersistenceController.java
index fb3278e..07e8c24 100644
--- 
a/modules/cassandra/store/src/main/java/org/apache/ignite/cache/store/cassandra/persistence/PersistenceController.java
+++ 
b/modules/cassandra/store/src/main/java/org/apache/ignite/cache/store/cassandra/persistence/PersistenceController.java
@@ -21,10 +21,7 @@ import com.datastax.driver.core.BoundStatement;
 import com.datastax.driver.core.PreparedStatement;
 import com.datastax.driver.core.Row;
 import java.nio.ByteBuffer;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.LinkedList;
-import java.util.List;
+import java.util.*;
 
 import org.apache.ignite.IgniteException;
 import org.apache.ignite.cache.store.cassandra.common.PropertyMappingHelper;
@@ -45,17 +42,29 @@ public class PersistenceController {
     /** List of value unique POJO fields (skipping aliases pointing to the 
same Cassandra table column). */
     private final List<PojoField> valUniquePojoFields;
 
-    /** CQL statement to insert row into Cassandra table. */
-    private final String writeStatement;
+    /** CQL statement template to insert row into Cassandra table. */
+    private final String writeStatementTempl;
 
-    /** CQL statement to delete row from Cassandra table. */
-    private final String delStatement;
+    /** CQL statement template to delete row from Cassandra table. */
+    private final String delStatementTempl;
 
-    /** CQL statement to select value fields from Cassandra table. */
-    private final String loadStatement;
+    /** CQL statement template to select value fields from Cassandra table. */
+    private final String loadStatementTempl;
 
-    /** CQL statement to select key/value fields from Cassandra table. */
-    private final String loadStatementWithKeyFields;
+    /** CQL statement template to select key/value fields from Cassandra 
table. */
+    private final String loadWithKeyFieldsStatementTempl;
+
+    /** CQL statements to insert row into Cassandra table. */
+    private volatile Map<String, String> writeStatements = new HashMap<>();
+
+    /** CQL statements to delete row from Cassandra table. */
+    private volatile Map<String, String> delStatements = new HashMap<>();
+
+    /** CQL statements to select value fields from Cassandra table. */
+    private volatile Map<String, String> loadStatements = new HashMap<>();
+
+    /** CQL statements to select key/value fields from Cassandra table. */
+    private volatile Map<String, String> loadWithKeyFieldsStatements = new 
HashMap<>();
 
     /**
      * Constructs persistence controller from Ignite cache persistence 
settings.
@@ -70,10 +79,10 @@ public class PersistenceController {
 
         String[] loadStatements = prepareLoadStatements();
 
-        loadStatementWithKeyFields = loadStatements[0];
-        loadStatement = loadStatements[1];
-        writeStatement = prepareWriteStatement();
-        delStatement = prepareDeleteStatement();
+        loadWithKeyFieldsStatementTempl = loadStatements[0];
+        loadStatementTempl = loadStatements[1];
+        writeStatementTempl = prepareWriteStatement();
+        delStatementTempl = prepareDeleteStatement();
 
         keyUniquePojoFields = 
settings.getKeyPersistenceSettings().cassandraUniqueFields();
 
@@ -118,50 +127,39 @@ public class PersistenceController {
     }
 
     /**
-     * Returns Cassandra keyspace to use.
-     *
-     * @return keyspace.
-     */
-    public String getKeyspace() {
-        return persistenceSettings.getKeyspace();
-    }
-
-    /**
-     * Returns Cassandra table to use.
-     *
-     * @return table.
-     */
-    public String getTable() {
-        return persistenceSettings.getTable();
-    }
-
-    /**
      * Returns CQL statement to insert row into Cassandra table.
      *
+     * @param table table name
+     *
      * @return CQL statement.
      */
-    public String getWriteStatement() {
-        return writeStatement;
+    public String getWriteStatement(String table) {
+        return getStatement(table, writeStatementTempl, writeStatements);
     }
 
     /**
      * Returns CQL statement to delete row from Cassandra table.
      *
+     * @param table table name
+     *
      * @return CQL statement.
      */
-    public String getDeleteStatement() {
-        return delStatement;
+    public String getDeleteStatement(String table) {
+        return getStatement(table, delStatementTempl, delStatements);
     }
 
     /**
      * Returns CQL statement to select key/value fields from Cassandra table.
      *
+     * @param table table name
      * @param includeKeyFields whether to include/exclude key fields from the 
returned row.
      *
      * @return CQL statement.
      */
-    public String getLoadStatement(boolean includeKeyFields) {
-        return includeKeyFields ? loadStatementWithKeyFields : loadStatement;
+    public String getLoadStatement(String table, boolean includeKeyFields) {
+        return includeKeyFields ?
+                getStatement(table, loadWithKeyFieldsStatementTempl, 
loadWithKeyFieldsStatements) :
+                getStatement(table, loadStatementTempl, loadStatements);
     }
 
     /**
@@ -248,8 +246,8 @@ public class PersistenceController {
             questionsList.append("?");
         }
 
-        String statement = "insert into \"" + 
persistenceSettings.getKeyspace() + "\".\"" +
-                persistenceSettings.getTable() + "\" (" + colsList + ") values 
(" + questionsList + ")";
+        String statement = "insert into \"" + 
persistenceSettings.getKeyspace() + "\".\"%1$s" +
+                "\" (" + colsList + ") values (" + questionsList + ")";
 
         if (persistenceSettings.getTTL() != null)
             statement += " using ttl " + persistenceSettings.getTTL();
@@ -276,10 +274,7 @@ public class PersistenceController {
 
         statement.append(";");
 
-        return "delete from \"" +
-            persistenceSettings.getKeyspace() + "\".\"" +
-            persistenceSettings.getTable() + "\" where " +
-            statement;
+        return "delete from \"" + persistenceSettings.getKeyspace() + 
"\".\"%1$s\" where " + statement;
     }
 
     /**
@@ -331,7 +326,7 @@ public class PersistenceController {
 
         statement.append(" from \"");
         statement.append(persistenceSettings.getKeyspace());
-        statement.append("\".\"").append(persistenceSettings.getTable());
+        statement.append("\".\"%1$s");
         statement.append("\" where ");
 
         int i = 0;
@@ -349,6 +344,20 @@ public class PersistenceController {
         return new String[] {hdrWithKeyFields + statement.toString(), hdr + 
statement.toString()};
     }
 
+    private String getStatement(final String table, final String template, 
final Map<String, String> statements) {
+        //noinspection SynchronizationOnLocalVariableOrMethodParameter
+        synchronized (statements) {
+            String st = statements.get(table);
+
+            if (st == null) {
+                st = String.format(template, table);
+                statements.put(table, st);
+            }
+
+            return st;
+        }
+    }
+
     /**
      * Builds object from Cassandra table row.
      *

http://git-wip-us.apache.org/repos/asf/ignite/blob/f0e4e06a/modules/cassandra/store/src/main/java/org/apache/ignite/cache/store/cassandra/session/BatchExecutionAssistant.java
----------------------------------------------------------------------
diff --git 
a/modules/cassandra/store/src/main/java/org/apache/ignite/cache/store/cassandra/session/BatchExecutionAssistant.java
 
b/modules/cassandra/store/src/main/java/org/apache/ignite/cache/store/cassandra/session/BatchExecutionAssistant.java
index e43db1d..093e289 100644
--- 
a/modules/cassandra/store/src/main/java/org/apache/ignite/cache/store/cassandra/session/BatchExecutionAssistant.java
+++ 
b/modules/cassandra/store/src/main/java/org/apache/ignite/cache/store/cassandra/session/BatchExecutionAssistant.java
@@ -38,6 +38,13 @@ public interface BatchExecutionAssistant<R, V> {
     public boolean tableExistenceRequired();
 
     /**
+     * Cassandra table to use for an operation.
+     *
+     * @return table name
+     */
+    public String getTable();
+
+    /**
      * Returns unbind CLQ statement for to be executed inside batch operation.
      *
      * @return Unbind CQL statement.

http://git-wip-us.apache.org/repos/asf/ignite/blob/f0e4e06a/modules/cassandra/store/src/main/java/org/apache/ignite/cache/store/cassandra/session/CassandraSessionImpl.java
----------------------------------------------------------------------
diff --git 
a/modules/cassandra/store/src/main/java/org/apache/ignite/cache/store/cassandra/session/CassandraSessionImpl.java
 
b/modules/cassandra/store/src/main/java/org/apache/ignite/cache/store/cassandra/session/CassandraSessionImpl.java
index 95b8581..d2c9e97 100644
--- 
a/modules/cassandra/store/src/main/java/org/apache/ignite/cache/store/cassandra/session/CassandraSessionImpl.java
+++ 
b/modules/cassandra/store/src/main/java/org/apache/ignite/cache/store/cassandra/session/CassandraSessionImpl.java
@@ -129,7 +129,7 @@ public class CassandraSessionImpl implements 
CassandraSession {
                 }
 
                 try {
-                    PreparedStatement preparedSt = 
prepareStatement(assistant.getStatement(),
+                    PreparedStatement preparedSt = 
prepareStatement(assistant.getTable(), assistant.getStatement(),
                         assistant.getPersistenceSettings(), 
assistant.tableExistenceRequired());
 
                     if (preparedSt == null)
@@ -151,7 +151,7 @@ public class CassandraSessionImpl implements 
CassandraSession {
                             return null;
                         }
 
-                        
handleTableAbsenceError(assistant.getPersistenceSettings());
+                        handleTableAbsenceError(assistant.getTable(), 
assistant.getPersistenceSettings());
                     }
                     else if (CassandraHelper.isHostsAvailabilityError(e))
                         handleHostsAvailabilityError(e, attempt, errorMsg);
@@ -210,7 +210,7 @@ public class CassandraSessionImpl implements 
CassandraSession {
 
                 List<Cache.Entry<Integer, ResultSetFuture>> futResults = new 
LinkedList<>();
 
-                PreparedStatement preparedSt = 
prepareStatement(assistant.getStatement(),
+                PreparedStatement preparedSt = 
prepareStatement(assistant.getTable(), assistant.getStatement(),
                     assistant.getPersistenceSettings(), 
assistant.tableExistenceRequired());
 
                 if (preparedSt == null)
@@ -232,7 +232,7 @@ public class CassandraSessionImpl implements 
CassandraSession {
                                     return assistant.processedData();
 
                                 tblAbsenceEx = e;
-                                
handleTableAbsenceError(assistant.getPersistenceSettings());
+                                handleTableAbsenceError(assistant.getTable(), 
assistant.getPersistenceSettings());
                             }
                             else if 
(CassandraHelper.isHostsAvailabilityError(e)) {
                                 hostsAvailEx = e;
@@ -307,7 +307,7 @@ public class CassandraSessionImpl implements 
CassandraSession {
                         return assistant.processedData();
 
                     error = tblAbsenceEx;
-                    
handleTableAbsenceError(assistant.getPersistenceSettings());
+                    handleTableAbsenceError(assistant.getTable(), 
assistant.getPersistenceSettings());
                 }
 
                 if (hostsAvailEx != null) {
@@ -475,7 +475,7 @@ public class CassandraSessionImpl implements 
CassandraSession {
      * @param tblExistenceRequired Flag indicating if table existence is 
required for the statement.
      * @return Prepared statement.
      */
-    private PreparedStatement prepareStatement(String statement, 
KeyValuePersistenceSettings settings,
+    private PreparedStatement prepareStatement(String table, String statement, 
KeyValuePersistenceSettings settings,
         boolean tblExistenceRequired) {
 
         int attempt = 0;
@@ -507,7 +507,7 @@ public class CassandraSessionImpl implements 
CassandraSession {
                         if (!tblExistenceRequired)
                             return null;
 
-                        handleTableAbsenceError(settings);
+                        handleTableAbsenceError(table, settings);
                     }
                     else if (CassandraHelper.isHostsAvailabilityError(e))
                         handleHostsAvailabilityError(e, attempt, errorMsg);
@@ -574,24 +574,25 @@ public class CassandraSessionImpl implements 
CassandraSession {
      *
      * @param settings Persistence settings.
      */
-    private void createTable(KeyValuePersistenceSettings settings) {
+    private void createTable(String table, KeyValuePersistenceSettings 
settings) {
         int attempt = 0;
         Throwable error = null;
-        String errorMsg = "Failed to create Cassandra table '" + 
settings.getTableFullName() + "'";
+        String tableFullName = settings.getKeyspace() + "." + table;
+        String errorMsg = "Failed to create Cassandra table '" + tableFullName 
+ "'";
 
         while (attempt < CQL_EXECUTION_ATTEMPTS_COUNT) {
             try {
                 
log.info("-----------------------------------------------------------------------");
-                log.info("Creating Cassandra table '" + 
settings.getTableFullName() + "'");
+                log.info("Creating Cassandra table '" + tableFullName + "'");
                 
log.info("-----------------------------------------------------------------------\n\n"
 +
-                    settings.getTableDDLStatement() + "\n");
+                        tableFullName + "\n");
                 
log.info("-----------------------------------------------------------------------");
-                session().execute(settings.getTableDDLStatement());
-                log.info("Cassandra table '" + settings.getTableFullName() + 
"' was successfully created");
+                session().execute(settings.getTableDDLStatement(table));
+                log.info("Cassandra table '" + tableFullName + "' was 
successfully created");
                 return;
             }
             catch (AlreadyExistsException ignored) {
-                log.info("Cassandra table '" + settings.getTableFullName() + 
"' already exist");
+                log.info("Cassandra table '" + tableFullName + "' already 
exist");
                 return;
             }
             catch (Throwable e) {
@@ -599,7 +600,7 @@ public class CassandraSessionImpl implements 
CassandraSession {
                     throw new IgniteException(errorMsg, e);
 
                 if (CassandraHelper.isKeyspaceAbsenceError(e)) {
-                    log.warning("Failed to create Cassandra table '" + 
settings.getTableFullName() +
+                    log.warning("Failed to create Cassandra table '" + 
tableFullName +
                         "' cause appropriate keyspace doesn't exist", e);
                     createKeyspace(settings);
                 }
@@ -620,19 +621,22 @@ public class CassandraSessionImpl implements 
CassandraSession {
      *
      * @param settings Persistence settings.
      */
-    private void createTableIndexes(KeyValuePersistenceSettings settings) {
-        if (settings.getIndexDDLStatements() == null || 
settings.getIndexDDLStatements().isEmpty())
+    private void createTableIndexes(String table, KeyValuePersistenceSettings 
settings) {
+        List<String> indexDDLStatements = 
settings.getIndexDDLStatements(table);
+
+        if (indexDDLStatements == null || indexDDLStatements.isEmpty())
             return;
 
         int attempt = 0;
         Throwable error = null;
-        String errorMsg = "Failed to create indexes for Cassandra table " + 
settings.getTableFullName();
+        String tableFullName = settings.getKeyspace() + "." + table;
+        String errorMsg = "Failed to create indexes for Cassandra table " + 
tableFullName;
 
         while (attempt < CQL_EXECUTION_ATTEMPTS_COUNT) {
             try {
-                log.info("Creating indexes for Cassandra table '" + 
settings.getTableFullName() + "'");
+                log.info("Creating indexes for Cassandra table '" + 
tableFullName + "'");
 
-                for (String statement : settings.getIndexDDLStatements()) {
+                for (String statement : indexDDLStatements) {
                     try {
                         session().execute(statement);
                     }
@@ -644,7 +648,7 @@ public class CassandraSessionImpl implements 
CassandraSession {
                     }
                 }
 
-                log.info("Indexes for Cassandra table '" + 
settings.getTableFullName() + "' were successfully created");
+                log.info("Indexes for Cassandra table '" + tableFullName + "' 
were successfully created");
 
                 return;
             }
@@ -652,7 +656,7 @@ public class CassandraSessionImpl implements 
CassandraSession {
                 if (CassandraHelper.isHostsAvailabilityError(e))
                     handleHostsAvailabilityError(e, attempt, errorMsg);
                 else if (CassandraHelper.isTableAbsenceError(e))
-                    createTable(settings);
+                    createTable(table, settings);
                 else
                     throw new IgniteException(errorMsg, e);
 
@@ -700,22 +704,24 @@ public class CassandraSessionImpl implements 
CassandraSession {
      *
      * @param settings Persistence settings.
      */
-    private void handleTableAbsenceError(KeyValuePersistenceSettings settings) 
{
+    private void handleTableAbsenceError(String table, 
KeyValuePersistenceSettings settings) {
         int hndNum = tblAbsenceHandlersCnt.incrementAndGet();
 
+        String tableFullName = settings.getKeyspace() + "." + table;
+
         try {
             synchronized (tblAbsenceHandlersCnt) {
                 // Oooops... I am not the first thread who tried to handle 
table absence problem.
                 if (hndNum != 0) {
-                    log.warning("Table " + settings.getTableFullName() + " 
absence problem detected. " +
+                    log.warning("Table " + tableFullName + " absence problem 
detected. " +
                             "Another thread already fixed it.");
                     return;
                 }
 
-                log.warning("Table " + settings.getTableFullName() + " absence 
problem detected. " +
+                log.warning("Table " + tableFullName + " absence problem 
detected. " +
                         "Trying to create table.");
 
-                IgniteException error = new IgniteException("Failed to create 
Cassandra table " + settings.getTableFullName());
+                IgniteException error = new IgniteException("Failed to create 
Cassandra table " + tableFullName);
 
                 int attempt = 0;
 
@@ -724,14 +730,14 @@ public class CassandraSessionImpl implements 
CassandraSession {
 
                     try {
                         createKeyspace(settings);
-                        createTable(settings);
-                        createTableIndexes(settings);
+                        createTable(table, settings);
+                        createTableIndexes(table, settings);
                     }
                     catch (Throwable e) {
                         if (CassandraHelper.isHostsAvailabilityError(e))
                             handleHostsAvailabilityError(e, attempt, null);
                         else
-                            throw new IgniteException("Failed to create 
Cassandra table " + settings.getTableFullName(), e);
+                            throw new IgniteException("Failed to create 
Cassandra table " + tableFullName, e);
 
                         error = (e instanceof IgniteException) ? 
(IgniteException)e : new IgniteException(e);
                     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/f0e4e06a/modules/cassandra/store/src/main/java/org/apache/ignite/cache/store/cassandra/session/ExecutionAssistant.java
----------------------------------------------------------------------
diff --git 
a/modules/cassandra/store/src/main/java/org/apache/ignite/cache/store/cassandra/session/ExecutionAssistant.java
 
b/modules/cassandra/store/src/main/java/org/apache/ignite/cache/store/cassandra/session/ExecutionAssistant.java
index 867f58d..cc625e0 100644
--- 
a/modules/cassandra/store/src/main/java/org/apache/ignite/cache/store/cassandra/session/ExecutionAssistant.java
+++ 
b/modules/cassandra/store/src/main/java/org/apache/ignite/cache/store/cassandra/session/ExecutionAssistant.java
@@ -30,14 +30,21 @@ import 
org.apache.ignite.cache.store.cassandra.persistence.KeyValuePersistenceSe
  */
 public interface ExecutionAssistant<R> {
     /**
-     * Indicates if Cassandra table existence is required for operation.
+     * Indicates if Cassandra table existence is required for an operation.
      *
      * @return true if table existence required.
      */
     public boolean tableExistenceRequired();
 
     /**
-     * Returns CQL statement to be used for operation.
+     * Cassandra table to use for an operation.
+     *
+     * @return table name
+     */
+    public String getTable();
+
+    /**
+     * Returns CQL statement to be used for an operation.
      *
      * @return CQL statement.
      */
@@ -53,7 +60,7 @@ public interface ExecutionAssistant<R> {
     public BoundStatement bindStatement(PreparedStatement statement);
 
     /**
-     * Persistence settings to use for operation.
+     * Persistence settings to use for an operation.
      *
      * @return persistence settings.
      */

http://git-wip-us.apache.org/repos/asf/ignite/blob/f0e4e06a/modules/cassandra/store/src/main/java/org/apache/ignite/cache/store/cassandra/utils/DDLGenerator.java
----------------------------------------------------------------------
diff --git 
a/modules/cassandra/store/src/main/java/org/apache/ignite/cache/store/cassandra/utils/DDLGenerator.java
 
b/modules/cassandra/store/src/main/java/org/apache/ignite/cache/store/cassandra/utils/DDLGenerator.java
index 19e21f0..e3ec391 100644
--- 
a/modules/cassandra/store/src/main/java/org/apache/ignite/cache/store/cassandra/utils/DDLGenerator.java
+++ 
b/modules/cassandra/store/src/main/java/org/apache/ignite/cache/store/cassandra/utils/DDLGenerator.java
@@ -46,16 +46,18 @@ public class DDLGenerator {
 
             try {
                 KeyValuePersistenceSettings settings = new 
KeyValuePersistenceSettings(file);
+                String table = settings.getTable() != null ? 
settings.getTable() : "my_table";
+
                 
System.out.println("-------------------------------------------------------------");
                 System.out.println("DDL for keyspace/table from file: " + arg);
                 
System.out.println("-------------------------------------------------------------");
                 System.out.println();
                 System.out.println(settings.getKeyspaceDDLStatement());
                 System.out.println();
-                System.out.println(settings.getTableDDLStatement());
+                System.out.println(settings.getTableDDLStatement(table));
                 System.out.println();
 
-                List<String> statements = settings.getIndexDDLStatements();
+                List<String> statements = 
settings.getIndexDDLStatements(table);
                 if (statements != null && !statements.isEmpty()) {
                     for (String st : statements) {
                         System.out.println(st);

http://git-wip-us.apache.org/repos/asf/ignite/blob/f0e4e06a/modules/cassandra/store/src/test/java/org/apache/ignite/tests/CassandraDirectPersistenceTest.java
----------------------------------------------------------------------
diff --git 
a/modules/cassandra/store/src/test/java/org/apache/ignite/tests/CassandraDirectPersistenceTest.java
 
b/modules/cassandra/store/src/test/java/org/apache/ignite/tests/CassandraDirectPersistenceTest.java
index 26cca68..9974898 100644
--- 
a/modules/cassandra/store/src/test/java/org/apache/ignite/tests/CassandraDirectPersistenceTest.java
+++ 
b/modules/cassandra/store/src/test/java/org/apache/ignite/tests/CassandraDirectPersistenceTest.java
@@ -299,6 +299,10 @@ public class CassandraDirectPersistenceTest {
             new 
ClassPathResource("org/apache/ignite/tests/persistence/pojo/persistence-settings-3.xml"),
             CassandraHelper.getAdminDataSrc());
 
+        CacheStore store4 = CacheStoreHelper.createCacheStore("persons",
+            new 
ClassPathResource("org/apache/ignite/tests/persistence/pojo/persistence-settings-4.xml"),
+            CassandraHelper.getAdminDataSrc());
+
         Collection<CacheEntryImpl<Long, Person>> entries1 = 
TestsHelper.generateLongsPersonsEntries();
         Collection<CacheEntryImpl<PersonId, Person>> entries2 = 
TestsHelper.generatePersonIdsPersonsEntries();
         Collection<CacheEntryImpl<PersonId, Person>> entries3 = 
TestsHelper.generatePersonIdsPersonsEntries();
@@ -309,12 +313,14 @@ public class CassandraDirectPersistenceTest {
         store1.write(entries1.iterator().next());
         store2.write(entries2.iterator().next());
         store3.write(entries3.iterator().next());
+        store4.write(entries3.iterator().next());
         LOGGER.info("Single operation write tests passed");
 
         LOGGER.info("Running bulk operation write tests");
         store1.writeAll(entries1);
         store2.writeAll(entries2);
         store3.writeAll(entries3);
+        store4.writeAll(entries3);
         LOGGER.info("Bulk operation write tests passed");
 
         LOGGER.info("POJO strategy write tests passed");
@@ -335,6 +341,10 @@ public class CassandraDirectPersistenceTest {
         if (!entries3.iterator().next().getValue().equals(person))
             throw new RuntimeException("Person values was incorrectly 
deserialized from Cassandra");
 
+        person = (Person)store4.load(entries3.iterator().next().getKey());
+        if (!entries3.iterator().next().getValue().equals(person))
+            throw new RuntimeException("Person values was incorrectly 
deserialized from Cassandra");
+
         LOGGER.info("Single operation read tests passed");
 
         LOGGER.info("Running bulk operation read tests");
@@ -351,6 +361,10 @@ public class CassandraDirectPersistenceTest {
         if (!TestsHelper.checkPersonCollectionsEqual(persons, entries3, false))
             throw new RuntimeException("Person values was incorrectly 
deserialized from Cassandra");
 
+        persons = store4.loadAll(TestsHelper.getKeys(entries3));
+        if (!TestsHelper.checkPersonCollectionsEqual(persons, entries3, false))
+            throw new RuntimeException("Person values was incorrectly 
deserialized from Cassandra");
+
         LOGGER.info("Bulk operation read tests passed");
 
         LOGGER.info("POJO strategy read tests passed");
@@ -366,6 +380,9 @@ public class CassandraDirectPersistenceTest {
         store3.delete(entries3.iterator().next().getKey());
         store3.deleteAll(TestsHelper.getKeys(entries3));
 
+        store4.delete(entries3.iterator().next().getKey());
+        store4.deleteAll(TestsHelper.getKeys(entries3));
+
         LOGGER.info("POJO strategy delete tests passed");
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/f0e4e06a/modules/cassandra/store/src/test/java/org/apache/ignite/tests/DDLGeneratorTest.java
----------------------------------------------------------------------
diff --git 
a/modules/cassandra/store/src/test/java/org/apache/ignite/tests/DDLGeneratorTest.java
 
b/modules/cassandra/store/src/test/java/org/apache/ignite/tests/DDLGeneratorTest.java
index 5de3097..43b6d3c 100644
--- 
a/modules/cassandra/store/src/test/java/org/apache/ignite/tests/DDLGeneratorTest.java
+++ 
b/modules/cassandra/store/src/test/java/org/apache/ignite/tests/DDLGeneratorTest.java
@@ -25,19 +25,33 @@ import org.junit.Test;
  * DDLGenerator test.
  */
 public class DDLGeneratorTest {
+    private static final String URL1 = 
"org/apache/ignite/tests/persistence/primitive/persistence-settings-1.xml";
+    private static final String URL2 = 
"org/apache/ignite/tests/persistence/pojo/persistence-settings-3.xml";
+    private static final String URL3 = 
"org/apache/ignite/tests/persistence/pojo/persistence-settings-4.xml";
+
     @Test
     @SuppressWarnings("unchecked")
     /** */
     public void generatorTest() {
         ClassLoader clsLdr = DDLGeneratorTest.class.getClassLoader();
 
-        URL url1 = 
clsLdr.getResource("org/apache/ignite/tests/persistence/primitive/persistence-settings-1.xml");
-        String file1 = url1.getFile(); // TODO IGNITE-1371 Possible NPE
+        URL url1 = clsLdr.getResource(URL1);
+        if (url1 == null)
+            throw new IllegalStateException("Failed to find resource: " + 
URL1);
+
+        URL url2 = clsLdr.getResource(URL2);
+        if (url2 == null)
+            throw new IllegalStateException("Failed to find resource: " + 
URL2);
+
+        URL url3 = clsLdr.getResource(URL3);
+        if (url3 == null)
+            throw new IllegalStateException("Failed to find resource: " + 
URL3);
 
-        URL url2 = 
clsLdr.getResource("org/apache/ignite/tests/persistence/pojo/persistence-settings-3.xml");
-        String file2 = url2.getFile();  // TODO IGNITE-1371 Possible NPE
+        String file1 = url1.getFile();
+        String file2 = url2.getFile();
+        String file3 = url3.getFile();
 
-        DDLGenerator.main(new String[]{file1, file2});
+        DDLGenerator.main(new String[]{file1, file2, file3});
     }
 
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/f0e4e06a/modules/cassandra/store/src/test/java/org/apache/ignite/tests/IgnitePersistentStoreTest.java
----------------------------------------------------------------------
diff --git 
a/modules/cassandra/store/src/test/java/org/apache/ignite/tests/IgnitePersistentStoreTest.java
 
b/modules/cassandra/store/src/test/java/org/apache/ignite/tests/IgnitePersistentStoreTest.java
index 8fa5cc5..8fdcf4c 100644
--- 
a/modules/cassandra/store/src/test/java/org/apache/ignite/tests/IgnitePersistentStoreTest.java
+++ 
b/modules/cassandra/store/src/test/java/org/apache/ignite/tests/IgnitePersistentStoreTest.java
@@ -249,6 +249,7 @@ public class IgnitePersistentStoreTest {
             IgniteCache<Long, Person> personCache1 = 
ignite.getOrCreateCache(new CacheConfiguration<Long, Person>("cache1"));
             IgniteCache<PersonId, Person> personCache2 = 
ignite.getOrCreateCache(new CacheConfiguration<PersonId, Person>("cache2"));
             IgniteCache<PersonId, Person> personCache3 = 
ignite.getOrCreateCache(new CacheConfiguration<PersonId, Person>("cache3"));
+            IgniteCache<PersonId, Person> personCache4 = 
ignite.getOrCreateCache(new CacheConfiguration<PersonId, Person>("cache4"));
 
             LOGGER.info("Running single operation write tests");
 
@@ -259,6 +260,7 @@ public class IgnitePersistentStoreTest {
 
             id = TestsHelper.generateRandomPersonId();
             personCache3.put(id, 
TestsHelper.generateRandomPerson(id.getPersonNumber()));
+            personCache4.put(id, 
TestsHelper.generateRandomPerson(id.getPersonNumber()));
 
             LOGGER.info("Single operation write tests passed");
 
@@ -266,6 +268,7 @@ public class IgnitePersistentStoreTest {
             personCache1.putAll(personMap1);
             personCache2.putAll(personMap2);
             personCache3.putAll(personMap2);
+            personCache4.putAll(personMap2);
             LOGGER.info("Bulk operation write tests passed");
         }
 
@@ -279,6 +282,7 @@ public class IgnitePersistentStoreTest {
             IgniteCache<Long, Person> personCache1 = 
ignite.getOrCreateCache(new CacheConfiguration<Long, Person>("cache1"));
             IgniteCache<PersonId, Person> personCache2 = 
ignite.getOrCreateCache(new CacheConfiguration<PersonId, Person>("cache2"));
             IgniteCache<PersonId, Person> personCache3 = 
ignite.getOrCreateCache(new CacheConfiguration<PersonId, Person>("cache3"));
+            IgniteCache<PersonId, Person> personCache4 = 
ignite.getOrCreateCache(new CacheConfiguration<PersonId, Person>("cache4"));
 
             LOGGER.info("Running single operation read tests");
             Person person = personCache1.get(1L);
@@ -295,6 +299,10 @@ public class IgnitePersistentStoreTest {
             if (!person.equals(personMap2.get(id)))
                 throw new RuntimeException("Person value was incorrectly 
deserialized from Cassandra");
 
+            person = personCache4.get(id);
+            if (!person.equals(personMap2.get(id)))
+                throw new RuntimeException("Person value was incorrectly 
deserialized from Cassandra");
+
             LOGGER.info("Single operation read tests passed");
 
             LOGGER.info("Running bulk operation read tests");
@@ -311,6 +319,10 @@ public class IgnitePersistentStoreTest {
             if (!TestsHelper.checkPersonMapsEqual(persons3, personMap2, false))
                 throw new RuntimeException("Person values batch was 
incorrectly deserialized from Cassandra");
 
+            Map<PersonId, Person> persons4 = 
personCache4.getAll(personMap2.keySet());
+            if (!TestsHelper.checkPersonMapsEqual(persons4, personMap2, false))
+                throw new RuntimeException("Person values batch was 
incorrectly deserialized from Cassandra");
+
             LOGGER.info("Bulk operation read tests passed");
 
             LOGGER.info("POJO strategy read tests passed");
@@ -326,6 +338,9 @@ public class IgnitePersistentStoreTest {
             personCache3.remove(id);
             personCache3.removeAll(personMap2.keySet());
 
+            personCache4.remove(id);
+            personCache4.removeAll(personMap2.keySet());
+
             LOGGER.info("POJO strategy delete tests passed");
         }
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/f0e4e06a/modules/cassandra/store/src/test/java/org/apache/ignite/tests/LoadTestsCassandraArtifactsCreator.java
----------------------------------------------------------------------
diff --git 
a/modules/cassandra/store/src/test/java/org/apache/ignite/tests/LoadTestsCassandraArtifactsCreator.java
 
b/modules/cassandra/store/src/test/java/org/apache/ignite/tests/LoadTestsCassandraArtifactsCreator.java
index 4fdb96f..33b11e1 100644
--- 
a/modules/cassandra/store/src/test/java/org/apache/ignite/tests/LoadTestsCassandraArtifactsCreator.java
+++ 
b/modules/cassandra/store/src/test/java/org/apache/ignite/tests/LoadTestsCassandraArtifactsCreator.java
@@ -62,14 +62,14 @@ public class LoadTestsCassandraArtifactsCreator {
             System.out.println("[INFO] Creating test table: " + 
perSettings.getTable());
 
             try {
-                
CassandraHelper.executeWithAdminCredentials(perSettings.getTableDDLStatement());
+                
CassandraHelper.executeWithAdminCredentials(perSettings.getTableDDLStatement(perSettings.getTable()));
             } catch (Throwable e) {
                 throw new RuntimeException("Failed to create test table: " + 
perSettings.getTable(), e);
             }
 
             System.out.println("[INFO] Test table '" + perSettings.getTable() 
+ "' was successfully created");
 
-            List<String> statements = perSettings.getIndexDDLStatements();
+            List<String> statements = 
perSettings.getIndexDDLStatements(perSettings.getTable());
             if (statements == null)
                 statements = new LinkedList<>();
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/f0e4e06a/modules/cassandra/store/src/test/resources/org/apache/ignite/tests/persistence/pojo/ignite-config.xml
----------------------------------------------------------------------
diff --git 
a/modules/cassandra/store/src/test/resources/org/apache/ignite/tests/persistence/pojo/ignite-config.xml
 
b/modules/cassandra/store/src/test/resources/org/apache/ignite/tests/persistence/pojo/ignite-config.xml
index cc1e8a6..b734a52 100644
--- 
a/modules/cassandra/store/src/test/resources/org/apache/ignite/tests/persistence/pojo/ignite-config.xml
+++ 
b/modules/cassandra/store/src/test/resources/org/apache/ignite/tests/persistence/pojo/ignite-config.xml
@@ -41,6 +41,11 @@
         <constructor-arg type="org.springframework.core.io.Resource" 
value="classpath:org/apache/ignite/tests/persistence/pojo/persistence-settings-3.xml"
 />
     </bean>
 
+    <!-- Persistence settings for 'cache4' -->
+    <bean id="cache4_persistence_settings" 
class="org.apache.ignite.cache.store.cassandra.persistence.KeyValuePersistenceSettings">
+        <constructor-arg type="org.springframework.core.io.Resource" 
value="classpath:org/apache/ignite/tests/persistence/pojo/persistence-settings-4.xml"
 />
+    </bean>
+
     <!-- Ignite configuration -->
     <bean id="ignite.cfg" 
class="org.apache.ignite.configuration.IgniteConfiguration">
         <property name="cacheConfiguration">
@@ -84,6 +89,19 @@
                     </property>
                 </bean>
 
+                <!-- Configuring persistence for "cache3" cache -->
+                <bean 
class="org.apache.ignite.configuration.CacheConfiguration">
+                    <property name="name" value="cache4"/>
+                    <property name="readThrough" value="true"/>
+                    <property name="writeThrough" value="true"/>
+                    <property name="cacheStoreFactory">
+                        <bean 
class="org.apache.ignite.cache.store.cassandra.CassandraCacheStoreFactory">
+                            <property name="dataSourceBean" 
value="cassandraAdminDataSource"/>
+                            <property name="persistenceSettingsBean" 
value="cache4_persistence_settings"/>
+                        </bean>
+                    </property>
+                </bean>
+
             </list>
         </property>
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/f0e4e06a/modules/cassandra/store/src/test/resources/org/apache/ignite/tests/persistence/pojo/persistence-settings-4.xml
----------------------------------------------------------------------
diff --git 
a/modules/cassandra/store/src/test/resources/org/apache/ignite/tests/persistence/pojo/persistence-settings-4.xml
 
b/modules/cassandra/store/src/test/resources/org/apache/ignite/tests/persistence/pojo/persistence-settings-4.xml
new file mode 100644
index 0000000..490d8e7
--- /dev/null
+++ 
b/modules/cassandra/store/src/test/resources/org/apache/ignite/tests/persistence/pojo/persistence-settings-4.xml
@@ -0,0 +1,175 @@
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You 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.
+-->
+
+<!--
+Root container for persistence settings configuration.
+
+Note: required element
+
+Attributes:
+  1) keyspace [required] - keyspace for Cassandra tables which should be used 
to store key/value pairs
+  2) table    [required] - Cassandra tables which should be used to store 
key/value pairs
+  3) ttl      [optional] - expiration period for the table rows (in seconds)
+-->
+<persistence keyspace="test1" ttl="86400">
+    <!--
+    Cassandra keyspace options which should be used to create provided 
keyspace if it doesn't exist.
+
+    Note: optional element
+    -->
+    <keyspaceOptions>
+        REPLICATION = {'class' : 'SimpleStrategy', 'replication_factor' : 3}
+        AND DURABLE_WRITES = true
+    </keyspaceOptions>
+
+    <!--
+    Cassandra table options which should be used to create provided table if 
it doesn't exist.
+
+    Note: optional element
+    -->
+    <tableOptions>
+        comment = 'A most excellent and useful table'
+        AND read_repair_chance = 0.2
+    </tableOptions>
+
+    <!--
+    Persistent settings for Ignite cache keys.
+
+    Note: required element
+
+    Attributes:
+      1) class      [required] - java class name for Ignite cache key
+      2) strategy   [required] - one of three possible persistent strategies 
which controls how object
+        should be persisted/loaded to/from Cassandra table:
+            a) PRIMITIVE - stores key value as is, by mapping it to Cassandra 
table column with corresponding type.
+                Should be used only for simple java types (int, long, String, 
double, Date) which could be mapped
+                to corresponding Cassadra types.
+            b) BLOB - stores key value as BLOB, by mapping it to Cassandra 
table column with blob type.
+                Could be used for any java object. Conversion of java object 
to BLOB is handled by "serializer"
+                which could be specified in serializer attribute (see below).
+            c) POJO - stores each field of an object as a column having 
corresponding type in Cassandra table.
+                Provides ability to utilize Cassandra secondary indexes for 
object fields.
+      3) serializer [optional] - specifies serializer class for BLOB strategy. 
Shouldn't be used for PRIMITIVE and
+        POJO strategies. Available implementations:
+            a) 
org.apache.ignite.cache.store.cassandra.serializer.JavaSerializer - uses 
standard Java
+                serialization framework
+            b) 
org.apache.ignite.cache.store.cassandra.serializer.KryoSerializer - uses Kryo
+                serialization framework
+      4) column     [optional] - specifies column name for PRIMITIVE and BLOB 
strategies where to store key value.
+        If not specified column having 'key' name will be used. Shouldn't be 
used for POJO strategy.
+    -->
+    <keyPersistence class="org.apache.ignite.tests.pojos.PersonId" 
strategy="POJO">
+        <!--
+        Partition key fields if POJO strategy used.
+
+        Note: optional element, only required for POJO strategy in case you 
want to manually specify
+            POJO fields to Cassandra columns mapping, instead of relying on 
dynamic discovering of
+            POJO fields and mapping them to the same columns of Cassandra 
table.
+        -->
+        <partitionKey>
+            <!--
+             Mapping from POJO field to Cassandra table column.
+
+             Note: required element
+
+             Attributes:
+               1) name   [required] - POJO field name
+               2) column [optional] - Cassandra table column name. If not 
specified lowercase
+                  POJO field name will be used.
+            -->
+            <field name="companyCode" column="company" />
+            <field name="departmentCode" column="department" />
+        </partitionKey>
+
+        <!--
+        Cluster key fields if POJO strategy used.
+
+        Note: optional element, only required for POJO strategy in case you 
want to manually specify
+            POJO fields to Cassandra columns mapping, instead of relying on 
dynamic discovering of
+            POJO fields and mapping them to the same columns of Cassandra 
table.
+        -->
+        <clusterKey>
+            <!--
+             Mapping from POJO field to Cassandra table column.
+
+             Note: required element
+
+             Attributes:
+               1) name   [required] - POJO field name
+               2) column [optional] - Cassandra table column name. If not 
specified lowercase
+                  POJO field name will be used.
+               3) sort   [optional] - specifies sort order (**asc** or 
**desc**)
+            -->
+            <field name="personNumber" column="number" sort="desc"/>
+        </clusterKey>
+    </keyPersistence>
+
+    <!--
+    Persistent settings for Ignite cache values.
+
+    Note: required element
+
+    Attributes:
+      1) class      [required] - java class name for Ignite cache value
+      2) strategy   [required] - one of three possible persistent strategies 
which controls how object
+        should be persisted/loaded to/from Cassandra table:
+            a) PRIMITIVE - stores key value as is, by mapping it to Cassandra 
table column with corresponding type.
+                Should be used only for simple java types (int, long, String, 
double, Date) which could be mapped
+                to corresponding Cassadra types.
+            b) BLOB - stores key value as BLOB, by mapping it to Cassandra 
table column with blob type.
+                Could be used for any java object. Conversion of java object 
to BLOB is handled by "serializer"
+                which could be specified in serializer attribute (see below).
+            c) POJO - stores each field of an object as a column having 
corresponding type in Cassandra table.
+                Provides ability to utilize Cassandra secondary indexes for 
object fields.
+      3) serializer [optional] - specifies serializer class for BLOB strategy. 
Shouldn't be used for PRIMITIVE and
+        POJO strategies. Available implementations:
+            a) 
org.apache.ignite.cache.store.cassandra.serializer.JavaSerializer - uses 
standard Java
+                serialization framework
+            b) 
org.apache.ignite.cache.store.cassandra.serializer.KryoSerializer - uses Kryo
+                serialization framework
+      4) column     [optional] - specifies column name for PRIMITIVE and BLOB 
strategies where to store value.
+        If not specified column having 'value' name will be used. Shouldn't be 
used for POJO strategy.
+    -->
+    <valuePersistence class="org.apache.ignite.tests.pojos.Person"
+                      strategy="POJO"
+                      
serializer="org.apache.ignite.cache.store.cassandra.serializer.JavaSerializer">
+        <!--
+         Mapping from POJO field to Cassandra table column.
+
+         Note: required element
+
+         Attributes:
+           1) name         [required] - POJO field name
+           2) column       [optional] - Cassandra table column name. If not 
specified lowercase
+              POJO field name will be used.
+           3) static       [optional] - boolean flag which specifies that 
column is static withing a given partition
+           4) index        [optional] - boolean flag specifying that secondary 
index should be created for the field
+           5) indexClass   [optional] - custom index java class name, in case 
you want to use custom index
+           6) indexOptions [optional] - custom index options
+        -->
+        <field name="personNumber" column="number" />
+        <field name="firstName" column="first_name" />
+        <field name="lastName" column="last_name" />
+        <field name="fullName" />
+        <field name="age" />
+        <field name="married" index="true"/>
+        <field name="height" />
+        <field name="weight" />
+        <field name="birthDate" column="birth_date" />
+        <field name="phones" />
+    </valuePersistence>
+</persistence>

Reply via email to