You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by vo...@apache.org on 2017/08/08 09:05:48 UTC

ignite git commit: IGNITE-5211: Added new constructor: QueryEntity(Class keyCls, Class valCls). This closes #2371. This closes #2388. This closes #2407.

Repository: ignite
Updated Branches:
  refs/heads/master 488a6d271 -> 9da69389e


IGNITE-5211: Added new constructor: QueryEntity(Class keyCls, Class valCls). This closes #2371. This closes #2388. This closes #2407.


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

Branch: refs/heads/master
Commit: 9da69389ed307357391e4eb87ae077751f30a58e
Parents: 488a6d2
Author: tledkov-gridgain <tl...@gridgain.com>
Authored: Tue Aug 8 12:05:36 2017 +0300
Committer: devozerov <vo...@gridgain.com>
Committed: Tue Aug 8 12:05:36 2017 +0300

----------------------------------------------------------------------
 .../org/apache/ignite/cache/QueryEntity.java    | 229 +++++++
 .../configuration/CacheConfiguration.java       | 615 +------------------
 .../cache/query/QueryEntityClassProperty.java   | 116 ++++
 .../cache/query/QueryEntityIndexDescriptor.java | 121 ++++
 .../cache/query/QueryEntityTypeDescriptor.java  | 219 +++++++
 .../h2/sql/AbstractH2CompareQueryTest.java      |   4 +-
 6 files changed, 693 insertions(+), 611 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/9da69389/modules/core/src/main/java/org/apache/ignite/cache/QueryEntity.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/cache/QueryEntity.java b/modules/core/src/main/java/org/apache/ignite/cache/QueryEntity.java
index 955e7d2..5180100 100644
--- a/modules/core/src/main/java/org/apache/ignite/cache/QueryEntity.java
+++ b/modules/core/src/main/java/org/apache/ignite/cache/QueryEntity.java
@@ -18,7 +18,9 @@
 package org.apache.ignite.cache;
 
 import java.io.Serializable;
+import java.lang.reflect.Field;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
@@ -27,10 +29,20 @@ import java.util.LinkedHashMap;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
+import javax.cache.CacheException;
+import org.apache.ignite.cache.query.annotations.QueryGroupIndex;
+import org.apache.ignite.cache.query.annotations.QuerySqlField;
+import org.apache.ignite.cache.query.annotations.QueryTextField;
+import org.apache.ignite.internal.processors.cache.query.QueryEntityClassProperty;
+import org.apache.ignite.internal.processors.cache.query.QueryEntityTypeDescriptor;
+import org.apache.ignite.internal.processors.query.GridQueryIndexDescriptor;
+import org.apache.ignite.internal.processors.query.QueryUtils;
 import org.apache.ignite.internal.util.tostring.GridToStringInclude;
 import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.internal.util.typedef.internal.A;
 import org.apache.ignite.internal.util.typedef.internal.S;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.jetbrains.annotations.Nullable;
 
 /**
  * Query entity is a description of {@link org.apache.ignite.IgniteCache cache} entry (composed of key and value)
@@ -111,6 +123,16 @@ public class QueryEntity implements Serializable {
     }
 
     /**
+     * Creates a query entity with the given key and value types.
+     *
+     * @param keyCls Key type.
+     * @param valCls Value type.
+     */
+    public QueryEntity(Class<?> keyCls, Class<?> valCls) {
+        this(convert(processKeyAndValueClasses(keyCls,valCls)));
+    }
+
+    /**
      * Gets key type for this query pair.
      *
      * @return Key type.
@@ -351,6 +373,213 @@ public class QueryEntity implements Serializable {
         return this;
     }
 
+    /**
+     * @param desc Type descriptor.
+     * @return Type metadata.
+     */
+    private static QueryEntity convert(QueryEntityTypeDescriptor desc) {
+        QueryEntity entity = new QueryEntity();
+
+        // Key and val types.
+        entity.setKeyType(desc.keyClass().getName());
+        entity.setValueType(desc.valueClass().getName());
+
+        for (QueryEntityClassProperty prop : desc.properties().values())
+            entity.addQueryField(prop.fullName(), U.box(prop.type()).getName(), prop.alias());
+
+        entity.setKeyFields(desc.keyProperties());
+
+        QueryIndex txtIdx = null;
+
+        Collection<QueryIndex> idxs = new ArrayList<>();
+
+        for (Map.Entry<String, GridQueryIndexDescriptor> idxEntry : desc.indexes().entrySet()) {
+            GridQueryIndexDescriptor idx = idxEntry.getValue();
+
+            if (idx.type() == QueryIndexType.FULLTEXT) {
+                assert txtIdx == null;
+
+                txtIdx = new QueryIndex();
+
+                txtIdx.setIndexType(QueryIndexType.FULLTEXT);
+
+                txtIdx.setFieldNames(idx.fields(), true);
+                txtIdx.setName(idxEntry.getKey());
+            }
+            else {
+                QueryIndex sortedIdx = new QueryIndex();
+
+                sortedIdx.setIndexType(idx.type());
+
+                LinkedHashMap<String, Boolean> fields = new LinkedHashMap<>();
+
+                for (String f : idx.fields())
+                    fields.put(f, !idx.descending(f));
+
+                sortedIdx.setFields(fields);
+
+                sortedIdx.setName(idxEntry.getKey());
+
+                idxs.add(sortedIdx);
+            }
+        }
+
+        if (desc.valueTextIndex()) {
+            if (txtIdx == null) {
+                txtIdx = new QueryIndex();
+
+                txtIdx.setIndexType(QueryIndexType.FULLTEXT);
+
+                txtIdx.setFieldNames(Arrays.asList(QueryUtils.VAL_FIELD_NAME), true);
+            }
+            else
+                txtIdx.getFields().put(QueryUtils.VAL_FIELD_NAME, true);
+        }
+
+        if (txtIdx != null)
+            idxs.add(txtIdx);
+
+        if (!F.isEmpty(idxs))
+            entity.setIndexes(idxs);
+
+        return entity;
+    }
+
+    /**
+     * @param keyCls Key class.
+     * @param valCls Value class.
+     * @return Type descriptor.
+     */
+    private static QueryEntityTypeDescriptor processKeyAndValueClasses(
+        Class<?> keyCls,
+        Class<?> valCls
+    ) {
+        QueryEntityTypeDescriptor d = new QueryEntityTypeDescriptor();
+
+        d.keyClass(keyCls);
+        d.valueClass(valCls);
+
+        processAnnotationsInClass(true, d.keyClass(), d, null);
+        processAnnotationsInClass(false, d.valueClass(), d, null);
+
+        return d;
+    }
+
+    /**
+     * Process annotations for class.
+     *
+     * @param key If given class relates to key.
+     * @param cls Class.
+     * @param type Type descriptor.
+     * @param parent Parent in case of embeddable.
+     */
+    private static void processAnnotationsInClass(boolean key, Class<?> cls, QueryEntityTypeDescriptor type,
+        @Nullable QueryEntityClassProperty parent) {
+        if (U.isJdk(cls) || QueryUtils.isGeometryClass(cls)) {
+            if (parent == null && !key && QueryUtils.isSqlType(cls)) { // We have to index primitive _val.
+                String idxName = cls.getSimpleName() + "_" + QueryUtils.VAL_FIELD_NAME + "_idx";
+
+                type.addIndex(idxName, QueryUtils.isGeometryClass(cls) ?
+                    QueryIndexType.GEOSPATIAL : QueryIndexType.SORTED);
+
+                type.addFieldToIndex(idxName, QueryUtils.VAL_FIELD_NAME, 0, false);
+            }
+
+            return;
+        }
+
+        if (parent != null && parent.knowsClass(cls))
+            throw new CacheException("Recursive reference found in type: " + cls.getName());
+
+        if (parent == null) { // Check class annotation at top level only.
+            QueryTextField txtAnnCls = cls.getAnnotation(QueryTextField.class);
+
+            if (txtAnnCls != null)
+                type.valueTextIndex(true);
+
+            QueryGroupIndex grpIdx = cls.getAnnotation(QueryGroupIndex.class);
+
+            if (grpIdx != null)
+                type.addIndex(grpIdx.name(), QueryIndexType.SORTED);
+
+            QueryGroupIndex.List grpIdxList = cls.getAnnotation(QueryGroupIndex.List.class);
+
+            if (grpIdxList != null && !F.isEmpty(grpIdxList.value())) {
+                for (QueryGroupIndex idx : grpIdxList.value())
+                    type.addIndex(idx.name(), QueryIndexType.SORTED);
+            }
+        }
+
+        for (Class<?> c = cls; c != null && !c.equals(Object.class); c = c.getSuperclass()) {
+            for (Field field : c.getDeclaredFields()) {
+                QuerySqlField sqlAnn = field.getAnnotation(QuerySqlField.class);
+                QueryTextField txtAnn = field.getAnnotation(QueryTextField.class);
+
+                if (sqlAnn != null || txtAnn != null) {
+                    QueryEntityClassProperty prop = new QueryEntityClassProperty(field);
+
+                    prop.parent(parent);
+
+                    // Add parent property before its possible nested properties so that
+                    // resulting parent column comes before columns corresponding to those
+                    // nested properties in the resulting table - that way nested
+                    // properties override will happen properly (first parent, then children).
+                    type.addProperty(prop, key, true);
+
+                    processAnnotation(key, sqlAnn, txtAnn, cls, c, field.getType(), prop, type);
+                }
+            }
+        }
+    }
+
+    /**
+     * Processes annotation at field or method.
+     *
+     * @param key If given class relates to key.
+     * @param sqlAnn SQL annotation, can be {@code null}.
+     * @param txtAnn H2 text annotation, can be {@code null}.
+     * @param cls Entity class.
+     * @param curCls Current entity class.
+     * @param fldCls Class of field or return type for method.
+     * @param prop Current property.
+     * @param desc Class description.
+     */
+    private static void processAnnotation(boolean key, QuerySqlField sqlAnn, QueryTextField txtAnn,
+        Class<?> cls, Class<?> curCls, Class<?> fldCls, QueryEntityClassProperty prop, QueryEntityTypeDescriptor desc) {
+        if (sqlAnn != null) {
+            processAnnotationsInClass(key, fldCls, desc, prop);
+
+            if (!sqlAnn.name().isEmpty())
+                prop.alias(sqlAnn.name());
+
+            if (sqlAnn.index()) {
+                String idxName = curCls.getSimpleName() + "_" + prop.alias() + "_idx";
+
+                if (cls != curCls)
+                    idxName = cls.getSimpleName() + "_" + idxName;
+
+                desc.addIndex(idxName, QueryUtils.isGeometryClass(prop.type()) ?
+                    QueryIndexType.GEOSPATIAL : QueryIndexType.SORTED);
+
+                desc.addFieldToIndex(idxName, prop.fullName(), 0, sqlAnn.descending());
+            }
+
+            if (!F.isEmpty(sqlAnn.groups())) {
+                for (String group : sqlAnn.groups())
+                    desc.addFieldToIndex(group, prop.fullName(), 0, false);
+            }
+
+            if (!F.isEmpty(sqlAnn.orderedGroups())) {
+                for (QuerySqlField.Group idx : sqlAnn.orderedGroups())
+                    desc.addFieldToIndex(idx.name(), prop.fullName(), idx.order(), idx.descending());
+            }
+        }
+
+        if (txtAnn != null)
+            desc.addFieldToTextIndex(prop.fullName());
+    }
+
+
     /** {@inheritDoc} */
     @Override public boolean equals(Object o) {
         if (this == o)

http://git-wip-us.apache.org/repos/asf/ignite/blob/9da69389/modules/core/src/main/java/org/apache/ignite/configuration/CacheConfiguration.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/configuration/CacheConfiguration.java b/modules/core/src/main/java/org/apache/ignite/configuration/CacheConfiguration.java
index 708913a..2b4ec1d 100644
--- a/modules/core/src/main/java/org/apache/ignite/configuration/CacheConfiguration.java
+++ b/modules/core/src/main/java/org/apache/ignite/configuration/CacheConfiguration.java
@@ -18,21 +18,10 @@
 package org.apache.ignite.configuration;
 
 import java.io.Serializable;
-import java.lang.reflect.AccessibleObject;
-import java.lang.reflect.Field;
-import java.lang.reflect.Member;
-import java.lang.reflect.Method;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
 import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeSet;
 import javax.cache.Cache;
 import javax.cache.CacheException;
 import javax.cache.configuration.CacheEntryListenerConfiguration;
@@ -53,26 +42,17 @@ import org.apache.ignite.cache.CacheRebalanceMode;
 import org.apache.ignite.cache.CacheWriteSynchronizationMode;
 import org.apache.ignite.cache.PartitionLossPolicy;
 import org.apache.ignite.cache.QueryEntity;
-import org.apache.ignite.cache.QueryIndex;
-import org.apache.ignite.cache.QueryIndexType;
 import org.apache.ignite.cache.affinity.AffinityFunction;
 import org.apache.ignite.cache.affinity.AffinityKeyMapper;
 import org.apache.ignite.cache.eviction.EvictionFilter;
 import org.apache.ignite.cache.eviction.EvictionPolicy;
-import org.apache.ignite.cache.query.annotations.QueryGroupIndex;
-import org.apache.ignite.cache.query.annotations.QuerySqlField;
 import org.apache.ignite.cache.query.annotations.QuerySqlFunction;
-import org.apache.ignite.cache.query.annotations.QueryTextField;
 import org.apache.ignite.cache.store.CacheStore;
 import org.apache.ignite.cache.store.CacheStoreSessionListener;
 import org.apache.ignite.cluster.ClusterNode;
 import org.apache.ignite.internal.binary.BinaryContext;
-import org.apache.ignite.internal.processors.query.GridQueryIndexDescriptor;
 import org.apache.ignite.internal.processors.query.QueryUtils;
-import org.apache.ignite.internal.util.tostring.GridToStringExclude;
-import org.apache.ignite.internal.util.tostring.GridToStringInclude;
 import org.apache.ignite.internal.util.typedef.F;
-import org.apache.ignite.internal.util.typedef.T2;
 import org.apache.ignite.internal.util.typedef.internal.A;
 import org.apache.ignite.internal.util.typedef.internal.S;
 import org.apache.ignite.internal.util.typedef.internal.U;
@@ -1768,14 +1748,12 @@ public class CacheConfiguration<K, V> extends MutableConfiguration<K, V> {
             Class<?> keyCls = newIndexedTypes[i];
             Class<?> valCls = newIndexedTypes[i + 1];
 
-            TypeDescriptor desc = processKeyAndValueClasses(keyCls, valCls);
-
-            QueryEntity converted = convert(desc);
+            QueryEntity newEntity = new QueryEntity(keyCls, valCls);
 
             boolean dup = false;
 
             for (QueryEntity entity : qryEntities) {
-                if (F.eq(entity.findValueType(), converted.findValueType())) {
+                if (F.eq(entity.findValueType(), newEntity.findValueType())) {
                     dup = true;
 
                     break;
@@ -1783,13 +1761,13 @@ public class CacheConfiguration<K, V> extends MutableConfiguration<K, V> {
             }
 
             if (!dup)
-                qryEntities.add(converted);
+                qryEntities.add(newEntity);
 
             // Set key configuration if needed.
-            String affFieldName = desc.affinityFieldName();
+            String affFieldName = BinaryContext.affinityFieldName(keyCls);
 
             if (affFieldName != null) {
-                CacheKeyConfiguration newKeyCfg = new CacheKeyConfiguration(converted.getKeyType(), affFieldName);
+                CacheKeyConfiguration newKeyCfg = new CacheKeyConfiguration(newEntity.getKeyType(), affFieldName);
 
                 if (F.isEmpty(keyCfg))
                     keyCfg = new CacheKeyConfiguration[] { newKeyCfg };
@@ -2041,77 +2019,6 @@ public class CacheConfiguration<K, V> extends MutableConfiguration<K, V> {
         return cfg;
     }
 
-    /**
-     * @param desc Type descriptor.
-     * @return Type metadata.
-     */
-    private static QueryEntity convert(TypeDescriptor desc) {
-        QueryEntity entity = new QueryEntity();
-
-        // Key and val types.
-        entity.setKeyType(desc.keyClass().getName());
-        entity.setValueType(desc.valueClass().getName());
-
-        for (ClassProperty prop : desc.props.values())
-            entity.addQueryField(prop.fullName(), U.box(prop.type()).getName(), prop.alias());
-
-        entity.setKeyFields(desc.keyProps);
-
-        QueryIndex txtIdx = null;
-
-        Collection<QueryIndex> idxs = new ArrayList<>();
-
-        for (Map.Entry<String, GridQueryIndexDescriptor> idxEntry : desc.indexes().entrySet()) {
-            GridQueryIndexDescriptor idx = idxEntry.getValue();
-
-            if (idx.type() == QueryIndexType.FULLTEXT) {
-                assert txtIdx == null;
-
-                txtIdx = new QueryIndex();
-
-                txtIdx.setIndexType(QueryIndexType.FULLTEXT);
-
-                txtIdx.setFieldNames(idx.fields(), true);
-                txtIdx.setName(idxEntry.getKey());
-            }
-            else {
-                QueryIndex sortedIdx = new QueryIndex();
-
-                sortedIdx.setIndexType(idx.type());
-
-                LinkedHashMap<String, Boolean> fields = new LinkedHashMap<>();
-
-                for (String f : idx.fields())
-                    fields.put(f, !idx.descending(f));
-
-                sortedIdx.setFields(fields);
-
-                sortedIdx.setName(idxEntry.getKey());
-
-                idxs.add(sortedIdx);
-            }
-        }
-
-        if (desc.valueTextIndex()) {
-            if (txtIdx == null) {
-                txtIdx = new QueryIndex();
-
-                txtIdx.setIndexType(QueryIndexType.FULLTEXT);
-
-                txtIdx.setFieldNames(Arrays.asList(QueryUtils.VAL_FIELD_NAME), true);
-            }
-            else
-                txtIdx.getFields().put(QueryUtils.VAL_FIELD_NAME, true);
-        }
-
-        if (txtIdx != null)
-            idxs.add(txtIdx);
-
-        if (!F.isEmpty(idxs))
-            entity.setIndexes(idxs);
-
-        return entity;
-    }
 
     /**
      * @param cls Class.
@@ -2123,141 +2030,6 @@ public class CacheConfiguration<K, V> extends MutableConfiguration<K, V> {
         return QueryUtils.isSqlType(cls) ? cls : Object.class;
     }
 
-    /**
-     * @param keyCls Key class.
-     * @param valCls Value class.
-     * @return Type descriptor.
-     */
-    static TypeDescriptor processKeyAndValueClasses(
-        Class<?> keyCls,
-        Class<?> valCls
-    ) {
-        TypeDescriptor d = new TypeDescriptor();
-
-        d.keyClass(keyCls);
-        d.valueClass(valCls);
-
-        d.affinityFieldName(BinaryContext.affinityFieldName(keyCls));
-
-        processAnnotationsInClass(true, d.keyCls, d, null);
-        processAnnotationsInClass(false, d.valCls, d, null);
-
-        return d;
-    }
-
-    /**
-     * Process annotations for class.
-     *
-     * @param key If given class relates to key.
-     * @param cls Class.
-     * @param type Type descriptor.
-     * @param parent Parent in case of embeddable.
-     */
-    private static void processAnnotationsInClass(boolean key, Class<?> cls, TypeDescriptor type,
-        @Nullable ClassProperty parent) {
-        if (U.isJdk(cls) || QueryUtils.isGeometryClass(cls)) {
-            if (parent == null && !key && QueryUtils.isSqlType(cls)) { // We have to index primitive _val.
-                String idxName = cls.getSimpleName() + "_" + QueryUtils.VAL_FIELD_NAME + "_idx";
-
-                type.addIndex(idxName, QueryUtils.isGeometryClass(cls) ?
-                    QueryIndexType.GEOSPATIAL : QueryIndexType.SORTED);
-
-                type.addFieldToIndex(idxName, QueryUtils.VAL_FIELD_NAME, 0, false);
-            }
-
-            return;
-        }
-
-        if (parent != null && parent.knowsClass(cls))
-            throw new CacheException("Recursive reference found in type: " + cls.getName());
-
-        if (parent == null) { // Check class annotation at top level only.
-            QueryTextField txtAnnCls = cls.getAnnotation(QueryTextField.class);
-
-            if (txtAnnCls != null)
-                type.valueTextIndex(true);
-
-            QueryGroupIndex grpIdx = cls.getAnnotation(QueryGroupIndex.class);
-
-            if (grpIdx != null)
-                type.addIndex(grpIdx.name(), QueryIndexType.SORTED);
-
-            QueryGroupIndex.List grpIdxList = cls.getAnnotation(QueryGroupIndex.List.class);
-
-            if (grpIdxList != null && !F.isEmpty(grpIdxList.value())) {
-                for (QueryGroupIndex idx : grpIdxList.value())
-                    type.addIndex(idx.name(), QueryIndexType.SORTED);
-            }
-        }
-
-        for (Class<?> c = cls; c != null && !c.equals(Object.class); c = c.getSuperclass()) {
-            for (Field field : c.getDeclaredFields()) {
-                QuerySqlField sqlAnn = field.getAnnotation(QuerySqlField.class);
-                QueryTextField txtAnn = field.getAnnotation(QueryTextField.class);
-
-                if (sqlAnn != null || txtAnn != null) {
-                    ClassProperty prop = new ClassProperty(field);
-
-                    prop.parent(parent);
-
-                    // Add parent property before its possible nested properties so that
-                    // resulting parent column comes before columns corresponding to those
-                    // nested properties in the resulting table - that way nested
-                    // properties override will happen properly (first parent, then children).
-                    type.addProperty(prop, key, true);
-
-                    processAnnotation(key, sqlAnn, txtAnn, cls, c, field.getType(), prop, type);
-                }
-            }
-        }
-    }
-
-    /**
-     * Processes annotation at field or method.
-     *
-     * @param key If given class relates to key.
-     * @param sqlAnn SQL annotation, can be {@code null}.
-     * @param txtAnn H2 text annotation, can be {@code null}.
-     * @param cls Entity class.
-     * @param curCls Current entity class.
-     * @param fldCls Class of field or return type for method.
-     * @param prop Current property.
-     * @param desc Class description.
-     */
-    private static void processAnnotation(boolean key, QuerySqlField sqlAnn, QueryTextField txtAnn,
-        Class<?> cls, Class<?> curCls, Class<?> fldCls, ClassProperty prop, TypeDescriptor desc) {
-        if (sqlAnn != null) {
-            processAnnotationsInClass(key, fldCls, desc, prop);
-
-            if (!sqlAnn.name().isEmpty())
-                prop.alias(sqlAnn.name());
-
-            if (sqlAnn.index()) {
-                String idxName = curCls.getSimpleName() + "_" + prop.alias() + "_idx";
-
-                if (cls != curCls)
-                    idxName = cls.getSimpleName() + "_" + idxName;
-
-                desc.addIndex(idxName, QueryUtils.isGeometryClass(prop.type()) ?
-                    QueryIndexType.GEOSPATIAL : QueryIndexType.SORTED);
-
-                desc.addFieldToIndex(idxName, prop.fullName(), 0, sqlAnn.descending());
-            }
-
-            if (!F.isEmpty(sqlAnn.groups())) {
-                for (String group : sqlAnn.groups())
-                    desc.addFieldToIndex(group, prop.fullName(), 0, false);
-            }
-
-            if (!F.isEmpty(sqlAnn.orderedGroups())) {
-                for (QuerySqlField.Group idx : sqlAnn.orderedGroups())
-                    desc.addFieldToIndex(idx.name(), prop.fullName(), idx.order(), idx.descending());
-            }
-        }
-
-        if (txtAnn != null)
-            desc.addFieldToTextIndex(prop.fullName());
-    }
 
     /** {@inheritDoc} */
     @Override public CacheConfiguration<K, V> setStatisticsEnabled(boolean enabled) {
@@ -2370,381 +2142,4 @@ public class CacheConfiguration<K, V> extends MutableConfiguration<K, V> {
             return "IgniteAllNodesPredicate []";
         }
     }
-
-    /**
-     * Descriptor of type.
-     */
-    private static class TypeDescriptor {
-        /** Value field names and types with preserved order. */
-        @GridToStringInclude
-        private final Map<String, Class<?>> fields = new LinkedHashMap<>();
-
-        /** */
-        @GridToStringExclude
-        private final Map<String, ClassProperty> props = new LinkedHashMap<>();
-
-        /** */
-        @GridToStringInclude
-        private final Set<String> keyProps = new HashSet<>();
-
-        /** */
-        @GridToStringInclude
-        private final Map<String, IndexDescriptor> indexes = new HashMap<>();
-
-        /** */
-        private IndexDescriptor fullTextIdx;
-
-        /** */
-        private Class<?> keyCls;
-
-        /** */
-        private Class<?> valCls;
-
-        /** */
-        private boolean valTextIdx;
-
-        /** Affinity field name. */
-        private String affFieldName;
-
-        /**
-         * @return Indexes.
-         */
-        public Map<String, GridQueryIndexDescriptor> indexes() {
-            return Collections.<String, GridQueryIndexDescriptor>unmodifiableMap(indexes);
-        }
-
-        /**
-         * Adds index.
-         *
-         * @param idxName Index name.
-         * @param type Index type.
-         * @param inlineSize Inline size.
-         * @return Index descriptor.
-         */
-        public IndexDescriptor addIndex(String idxName, QueryIndexType type, int inlineSize) {
-            IndexDescriptor idx = new IndexDescriptor(type, inlineSize);
-
-            if (indexes.put(idxName, idx) != null)
-                throw new CacheException("Index with name '" + idxName + "' already exists.");
-
-            return idx;
-        }
-
-        /**
-         * Adds index.
-         *
-         * @param idxName Index name.
-         * @param type Index type.
-         * @return Index descriptor.
-         */
-        public IndexDescriptor addIndex(String idxName, QueryIndexType type) {
-            return addIndex(idxName, type, -1);
-        }
-
-        /**
-         * Adds field to index.
-         *
-         * @param idxName Index name.
-         * @param field Field name.
-         * @param orderNum Fields order number in index.
-         * @param descending Sorting order.
-         */
-        public void addFieldToIndex(String idxName, String field, int orderNum,
-            boolean descending) {
-            IndexDescriptor desc = indexes.get(idxName);
-
-            if (desc == null)
-                desc = addIndex(idxName, QueryIndexType.SORTED);
-
-            desc.addField(field, orderNum, descending);
-        }
-
-        /**
-         * Adds field to text index.
-         *
-         * @param field Field name.
-         */
-        public void addFieldToTextIndex(String field) {
-            if (fullTextIdx == null) {
-                fullTextIdx = new IndexDescriptor(QueryIndexType.FULLTEXT);
-
-                indexes.put(null, fullTextIdx);
-            }
-
-            fullTextIdx.addField(field, 0, false);
-        }
-
-        /**
-         * @return Value class.
-         */
-        public Class<?> valueClass() {
-            return valCls;
-        }
-
-        /**
-         * Sets value class.
-         *
-         * @param valCls Value class.
-         */
-        void valueClass(Class<?> valCls) {
-            this.valCls = valCls;
-        }
-
-        /**
-         * @return Key class.
-         */
-        public Class<?> keyClass() {
-            return keyCls;
-        }
-
-        /**
-         * Set key class.
-         *
-         * @param keyCls Key class.
-         */
-        void keyClass(Class<?> keyCls) {
-            this.keyCls = keyCls;
-        }
-
-        /**
-         * @return Affinity field name.
-         */
-        @Nullable public String affinityFieldName() {
-            return affFieldName;
-        }
-
-        /**
-         * @param affFieldName Affinity field name.
-         */
-        private void affinityFieldName(@Nullable String affFieldName) {
-            this.affFieldName = affFieldName;
-        }
-
-        /**
-         * Adds property to the type descriptor.
-         *
-         * @param prop Property.
-         * @param key Property ownership flag (key or not).
-         * @param failOnDuplicate Fail on duplicate flag.
-         */
-        void addProperty(ClassProperty prop, boolean key, boolean failOnDuplicate) {
-            String name = prop.fullName();
-
-            if (props.put(name, prop) != null && failOnDuplicate)
-                throw new CacheException("Property with name '" + name + "' already exists.");
-
-            fields.put(name, prop.type());
-
-            if (key)
-                keyProps.add(name);
-        }
-
-        /**
-         * @return {@code true} If we need to have a fulltext index on value.
-         */
-        public boolean valueTextIndex() {
-            return valTextIdx;
-        }
-
-        /**
-         * Sets if this value should be text indexed.
-         *
-         * @param valTextIdx Flag value.
-         */
-        public void valueTextIndex(boolean valTextIdx) {
-            this.valTextIdx = valTextIdx;
-        }
-
-        /** {@inheritDoc} */
-        @Override public String toString() {
-            return S.toString(TypeDescriptor.class, this);
-        }
-    }
-
-    /**
-     * Index descriptor.
-     */
-    private static class IndexDescriptor implements GridQueryIndexDescriptor {
-        /** Fields sorted by order number. */
-        private final Collection<T2<String, Integer>> fields = new TreeSet<>(
-            new Comparator<T2<String, Integer>>() {
-                @Override public int compare(T2<String, Integer> o1, T2<String, Integer> o2) {
-                    if (o1.get2().equals(o2.get2())) // Order is equal, compare field names to avoid replace in Set.
-                        return o1.get1().compareTo(o2.get1());
-
-                    return o1.get2() < o2.get2() ? -1 : 1;
-                }
-            });
-
-        /** Fields which should be indexed in descending order. */
-        private Collection<String> descendings;
-
-        /** */
-        private final QueryIndexType type;
-
-        /** */
-        private final int inlineSize;
-
-        /**
-         * @param type Type.
-         * @param inlineSize Inline size.
-         */
-        private IndexDescriptor(QueryIndexType type, int inlineSize) {
-            assert type != null;
-
-            this.type = type;
-            this.inlineSize = inlineSize;
-        }
-
-        /**
-         * @param type Type.
-         */
-        private IndexDescriptor(QueryIndexType type) {
-            this(type, -1);
-        }
-
-        /** {@inheritDoc} */
-        @Override public String name() {
-            return null;
-        }
-
-        /** {@inheritDoc} */
-        @Override public Collection<String> fields() {
-            Collection<String> res = new ArrayList<>(fields.size());
-
-            for (T2<String, Integer> t : fields)
-                res.add(t.get1());
-
-            return res;
-        }
-
-        /** {@inheritDoc} */
-        @Override public boolean descending(String field) {
-            return descendings != null && descendings.contains(field);
-        }
-
-        /**
-         * Adds field to this index.
-         *
-         * @param field Field name.
-         * @param orderNum Field order number in this index.
-         * @param descending Sort order.
-         */
-        public void addField(String field, int orderNum, boolean descending) {
-            fields.add(new T2<>(field, orderNum));
-
-            if (descending) {
-                if (descendings == null)
-                    descendings = new HashSet<>();
-
-                descendings.add(field);
-            }
-        }
-
-        /** {@inheritDoc} */
-        @Override public QueryIndexType type() {
-            return type;
-        }
-
-        /** {@inheritDoc} */
-        @Override public int inlineSize() {
-            return inlineSize;
-        }
-
-        /** {@inheritDoc} */
-        @Override public String toString() {
-            return S.toString(IndexDescriptor.class, this);
-        }
-    }
-
-    /**
-     * Description of type property.
-     */
-    private static class ClassProperty {
-        /** */
-        private final Member member;
-
-        /** */
-        private ClassProperty parent;
-
-        /** */
-        private String name;
-
-        /** */
-        private String alias;
-
-        /**
-         * Constructor.
-         *
-         * @param member Element.
-         */
-        ClassProperty(Member member) {
-            this.member = member;
-
-            name = member.getName();
-
-            if (member instanceof Method) {
-                if (member.getName().startsWith("get") && member.getName().length() > 3)
-                    name = member.getName().substring(3);
-
-                if (member.getName().startsWith("is") && member.getName().length() > 2)
-                    name = member.getName().substring(2);
-            }
-
-            ((AccessibleObject)member).setAccessible(true);
-        }
-
-        /**
-         * @param alias Alias.
-         */
-        public void alias(String alias) {
-            this.alias = alias;
-        }
-
-        /**
-         * @return Alias.
-         */
-        String alias() {
-            return F.isEmpty(alias) ? name : alias;
-        }
-
-        /**
-         * @return Type.
-         */
-        public Class<?> type() {
-            return member instanceof Field ? ((Field)member).getType() : ((Method)member).getReturnType();
-        }
-
-        /**
-         * @param parent Parent property if this is embeddable element.
-         */
-        public void parent(ClassProperty parent) {
-            this.parent = parent;
-        }
-
-        /** {@inheritDoc} */
-        @Override public String toString() {
-            return S.toString(ClassProperty.class, this);
-        }
-
-        /**
-         * @param cls Class.
-         * @return {@code true} If this property or some parent relates to member of the given class.
-         */
-        public boolean knowsClass(Class<?> cls) {
-            return member.getDeclaringClass() == cls || (parent != null && parent.knowsClass(cls));
-        }
-
-        /**
-         * @return Full name with all parents in dot notation.
-         */
-        public String fullName() {
-            assert name != null;
-
-            if (parent == null)
-                return name;
-
-            return parent.fullName() + '.' + name;
-        }
-    }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/9da69389/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/QueryEntityClassProperty.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/QueryEntityClassProperty.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/QueryEntityClassProperty.java
new file mode 100644
index 0000000..e21b73c
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/QueryEntityClassProperty.java
@@ -0,0 +1,116 @@
+/*
+ * 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.
+ */
+
+package org.apache.ignite.internal.processors.cache.query;
+
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.Field;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.internal.S;
+
+/**
+ * Description of type property.
+ */
+public class QueryEntityClassProperty {
+    /** */
+    private final Member member;
+
+    /** */
+    private QueryEntityClassProperty parent;
+
+    /** */
+    private String name;
+
+    /** */
+    private String alias;
+
+    /**
+     * Constructor.
+     *
+     * @param member Element.
+     */
+    public QueryEntityClassProperty(Member member) {
+        this.member = member;
+
+        name = member.getName();
+
+        if (member instanceof Method) {
+            if (member.getName().startsWith("get") && member.getName().length() > 3)
+                name = member.getName().substring(3);
+
+            if (member.getName().startsWith("is") && member.getName().length() > 2)
+                name = member.getName().substring(2);
+        }
+
+        ((AccessibleObject)member).setAccessible(true);
+    }
+
+    /**
+     * @param alias Alias.
+     */
+    public void alias(String alias) {
+        this.alias = alias;
+    }
+
+    /**
+     * @return Alias.
+     */
+    public String alias() {
+        return F.isEmpty(alias) ? name : alias;
+    }
+
+    /**
+     * @return Type.
+     */
+    public Class<?> type() {
+        return member instanceof Field ? ((Field)member).getType() : ((Method)member).getReturnType();
+    }
+
+    /**
+     * @param parent Parent property if this is embeddable element.
+     */
+    public void parent(QueryEntityClassProperty parent) {
+        this.parent = parent;
+    }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        return S.toString(QueryEntityClassProperty.class, this);
+    }
+
+    /**
+     * @param cls Class.
+     * @return {@code true} If this property or some parent relates to member of the given class.
+     */
+    public boolean knowsClass(Class<?> cls) {
+        return member.getDeclaringClass() == cls || (parent != null && parent.knowsClass(cls));
+    }
+
+    /**
+     * @return Full name with all parents in dot notation.
+     */
+    public String fullName() {
+        assert name != null;
+
+        if (parent == null)
+            return name;
+
+        return parent.fullName() + '.' + name;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/9da69389/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/QueryEntityIndexDescriptor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/QueryEntityIndexDescriptor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/QueryEntityIndexDescriptor.java
new file mode 100644
index 0000000..2fb5837
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/QueryEntityIndexDescriptor.java
@@ -0,0 +1,121 @@
+/*
+ * 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.
+ */
+
+package org.apache.ignite.internal.processors.cache.query;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.TreeSet;
+import org.apache.ignite.cache.QueryIndexType;
+import org.apache.ignite.internal.processors.query.GridQueryIndexDescriptor;
+import org.apache.ignite.internal.util.typedef.T2;
+import org.apache.ignite.internal.util.typedef.internal.S;
+
+/**
+ * Index descriptor.
+ */
+public class QueryEntityIndexDescriptor implements GridQueryIndexDescriptor {
+    /** Fields sorted by order number. */
+    private final Collection<T2<String, Integer>> fields = new TreeSet<>(
+        new Comparator<T2<String, Integer>>() {
+            @Override public int compare(T2<String, Integer> o1, T2<String, Integer> o2) {
+                if (o1.get2().equals(o2.get2())) // Order is equal, compare field names to avoid replace in Set.
+                    return o1.get1().compareTo(o2.get1());
+
+                return o1.get2() < o2.get2() ? -1 : 1;
+            }
+        });
+    /** */
+    private final QueryIndexType type;
+    /** */
+    private final int inlineSize;
+    /** Fields which should be indexed in descending order. */
+    private Collection<String> descendings;
+
+    /**
+     * @param type Type.
+     * @param inlineSize Inline size.
+     */
+    QueryEntityIndexDescriptor(QueryIndexType type, int inlineSize) {
+        assert type != null;
+
+        this.type = type;
+        this.inlineSize = inlineSize;
+    }
+
+    /**
+     * @param type Type.
+     */
+    QueryEntityIndexDescriptor(QueryIndexType type) {
+        this(type, -1);
+    }
+
+    /** {@inheritDoc} */
+    @Override public String name() {
+        return null;
+    }
+
+    /** {@inheritDoc} */
+    @Override public Collection<String> fields() {
+        Collection<String> res = new ArrayList<>(fields.size());
+
+        for (T2<String, Integer> t : fields)
+            res.add(t.get1());
+
+        return res;
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean descending(String field) {
+        return descendings != null && descendings.contains(field);
+    }
+
+    /**
+     * Adds field to this index.
+     *
+     * @param field Field name.
+     * @param orderNum Field order number in this index.
+     * @param descending Sort order.
+     */
+    public void addField(String field, int orderNum, boolean descending) {
+        fields.add(new T2<>(field, orderNum));
+
+        if (descending) {
+            if (descendings == null)
+                descendings = new HashSet<>();
+
+            descendings.add(field);
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override public QueryIndexType type() {
+        return type;
+    }
+
+    /** {@inheritDoc} */
+    @Override public int inlineSize() {
+        return inlineSize;
+    }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        return S.toString(QueryEntityIndexDescriptor.class, this);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/9da69389/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/QueryEntityTypeDescriptor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/QueryEntityTypeDescriptor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/QueryEntityTypeDescriptor.java
new file mode 100644
index 0000000..47ab263
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/QueryEntityTypeDescriptor.java
@@ -0,0 +1,219 @@
+/*
+ * 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.
+ */
+
+package org.apache.ignite.internal.processors.cache.query;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Set;
+import javax.cache.CacheException;
+import org.apache.ignite.cache.QueryIndexType;
+import org.apache.ignite.internal.processors.query.GridQueryIndexDescriptor;
+import org.apache.ignite.internal.util.tostring.GridToStringExclude;
+import org.apache.ignite.internal.util.tostring.GridToStringInclude;
+import org.apache.ignite.internal.util.typedef.internal.S;
+
+/**
+ * Descriptor of type.
+ */
+public class QueryEntityTypeDescriptor {
+    /** Value field names and types with preserved order. */
+    @GridToStringInclude
+    private final Map<String, Class<?>> fields = new LinkedHashMap<>();
+
+    /** */
+    @GridToStringExclude
+    private final Map<String, QueryEntityClassProperty> props = new LinkedHashMap<>();
+
+    /** */
+    @GridToStringInclude
+    private final Set<String> keyProps = new HashSet<>();
+
+    /** */
+    @GridToStringInclude
+    private final Map<String, QueryEntityIndexDescriptor> indexes = new HashMap<>();
+
+    /** */
+    private QueryEntityIndexDescriptor fullTextIdx;
+
+    /** */
+    private Class<?> keyCls;
+
+    /** */
+    private Class<?> valCls;
+
+    /** */
+    private boolean valTextIdx;
+
+    /**
+     * @return Indexes.
+     */
+    public Map<String, GridQueryIndexDescriptor> indexes() {
+        return Collections.<String, GridQueryIndexDescriptor>unmodifiableMap(indexes);
+    }
+
+    /**
+     * Adds index.
+     *
+     * @param idxName Index name.
+     * @param type Index type.
+     * @param inlineSize Inline size.
+     * @return Index descriptor.
+     */
+    public QueryEntityIndexDescriptor addIndex(String idxName, QueryIndexType type, int inlineSize) {
+        QueryEntityIndexDescriptor idx = new QueryEntityIndexDescriptor(type, inlineSize);
+
+        if (indexes.put(idxName, idx) != null)
+            throw new CacheException("Index with name '" + idxName + "' already exists.");
+
+        return idx;
+    }
+
+    /**
+     * Adds index.
+     *
+     * @param idxName Index name.
+     * @param type Index type.
+     * @return Index descriptor.
+     */
+    public QueryEntityIndexDescriptor addIndex(String idxName, QueryIndexType type) {
+        return addIndex(idxName, type, -1);
+    }
+
+    /**
+     * Adds field to index.
+     *
+     * @param idxName Index name.
+     * @param field Field name.
+     * @param orderNum Fields order number in index.
+     * @param descending Sorting order.
+     */
+    public void addFieldToIndex(String idxName, String field, int orderNum,
+        boolean descending) {
+        QueryEntityIndexDescriptor desc = indexes.get(idxName);
+
+        if (desc == null)
+            desc = addIndex(idxName, QueryIndexType.SORTED);
+
+        desc.addField(field, orderNum, descending);
+    }
+
+    /**
+     * Adds field to text index.
+     *
+     * @param field Field name.
+     */
+    public void addFieldToTextIndex(String field) {
+        if (fullTextIdx == null) {
+            fullTextIdx = new QueryEntityIndexDescriptor(QueryIndexType.FULLTEXT);
+
+            indexes.put(null, fullTextIdx);
+        }
+
+        fullTextIdx.addField(field, 0, false);
+    }
+
+    /**
+     * @return Value class.
+     */
+    public Class<?> valueClass() {
+        return valCls;
+    }
+
+    /**
+     * Sets value class.
+     *
+     * @param valCls Value class.
+     */
+    public void valueClass(Class<?> valCls) {
+        this.valCls = valCls;
+    }
+
+    /**
+     * @return Key class.
+     */
+    public Class<?> keyClass() {
+        return keyCls;
+    }
+
+    /**
+     * Set key class.
+     *
+     * @param keyCls Key class.
+     */
+    public void keyClass(Class<?> keyCls) {
+        this.keyCls = keyCls;
+    }
+
+    /**
+     * Adds property to the type descriptor.
+     *
+     * @param prop Property.
+     * @param key Property ownership flag (key or not).
+     * @param failOnDuplicate Fail on duplicate flag.
+     */
+    public void addProperty(QueryEntityClassProperty prop, boolean key, boolean failOnDuplicate) {
+        String name = prop.fullName();
+
+        if (props.put(name, prop) != null && failOnDuplicate)
+            throw new CacheException("Property with name '" + name + "' already exists.");
+
+        fields.put(name, prop.type());
+
+        if (key)
+            keyProps.add(name);
+    }
+
+    /**
+     * @return Class properties.
+     */
+    public Map<String, QueryEntityClassProperty> properties() {
+        return props;
+    }
+
+    /**
+     * @return Properties keys.
+     */
+    public Set<String> keyProperties() {
+        return keyProps;
+    }
+
+    /**
+     * @return {@code true} If we need to have a fulltext index on value.
+     */
+    public boolean valueTextIndex() {
+        return valTextIdx;
+    }
+
+    /**
+     * Sets if this value should be text indexed.
+     *
+     * @param valTextIdx Flag value.
+     */
+    public void valueTextIndex(boolean valTextIdx) {
+        this.valTextIdx = valTextIdx;
+    }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        return S.toString(QueryEntityTypeDescriptor.class, this);
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/ignite/blob/9da69389/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/sql/AbstractH2CompareQueryTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/sql/AbstractH2CompareQueryTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/sql/AbstractH2CompareQueryTest.java
index 5475311..1ddd252 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/sql/AbstractH2CompareQueryTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/sql/AbstractH2CompareQueryTest.java
@@ -25,6 +25,7 @@ import java.sql.ResultSetMetaData;
 import java.sql.SQLException;
 import java.sql.Statement;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
@@ -34,6 +35,7 @@ import org.apache.ignite.IgniteCache;
 import org.apache.ignite.cache.CacheAtomicityMode;
 import org.apache.ignite.cache.CacheMode;
 import org.apache.ignite.cache.CacheWriteSynchronizationMode;
+import org.apache.ignite.cache.QueryEntity;
 import org.apache.ignite.cache.query.SqlFieldsQuery;
 import org.apache.ignite.configuration.CacheConfiguration;
 import org.apache.ignite.configuration.IgniteConfiguration;
@@ -94,7 +96,7 @@ public abstract class AbstractH2CompareQueryTest extends GridCommonAbstractTest
         cc.setCacheMode(mode);
         cc.setWriteSynchronizationMode(CacheWriteSynchronizationMode.FULL_SYNC);
         cc.setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL);
-        cc.setIndexedTypes(clsK, clsV);
+        cc.setQueryEntities(Collections.singleton(new QueryEntity(clsK, clsV)));
 
         return cc;
     }