You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ak...@apache.org on 2015/10/29 16:33:16 UTC

ignite git commit: IGNITE-1753 Implemented hasher + minor fixes.

Repository: ignite
Updated Branches:
  refs/heads/ignite-1753-1282 d5355def6 -> 000152272


IGNITE-1753 Implemented hasher + minor fixes.


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

Branch: refs/heads/ignite-1753-1282
Commit: 000152272a396c133b25aad76c9bdc043fa811d9
Parents: d5355de
Author: AKuznetsov <ak...@gridgain.com>
Authored: Thu Oct 29 22:32:29 2015 +0700
Committer: AKuznetsov <ak...@gridgain.com>
Committed: Thu Oct 29 22:32:29 2015 +0700

----------------------------------------------------------------------
 .../store/jdbc/CacheAbstractJdbcStore.java      | 82 +++++++----------
 .../cache/store/jdbc/CacheJdbcPojoStore.java    | 93 +++++++++++++-------
 .../jdbc/CacheJdbcPojoStoreConfiguration.java   | 27 +++---
 .../ignite/cache/store/jdbc/JdbcType.java       |  2 +-
 .../store/jdbc/JdbcTypeDefaultHashBuilder.java  | 23 -----
 .../jdbc/JdbcTypeDefaultHashBuilderFactory.java | 19 ----
 .../cache/store/jdbc/JdbcTypeDefaultHasher.java | 31 +++++++
 .../cache/store/jdbc/JdbcTypeHashBuilder.java   | 38 --------
 .../ignite/cache/store/jdbc/JdbcTypeHasher.java | 37 ++++++++
 9 files changed, 177 insertions(+), 175 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/00015227/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/CacheAbstractJdbcStore.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/CacheAbstractJdbcStore.java b/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/CacheAbstractJdbcStore.java
index c43a030..12a7109 100644
--- a/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/CacheAbstractJdbcStore.java
+++ b/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/CacheAbstractJdbcStore.java
@@ -42,7 +42,6 @@ import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReentrantLock;
 import javax.cache.Cache;
 import javax.cache.CacheException;
-import javax.cache.configuration.Factory;
 import javax.cache.integration.CacheLoaderException;
 import javax.cache.integration.CacheWriterException;
 import javax.sql.DataSource;
@@ -192,8 +191,8 @@ public abstract class CacheAbstractJdbcStore<K, V> implements CacheStore<K, V>,
     /** Types that store could process. */
     private JdbcType[] types;
 
-    /** Factory for.  */
-    protected Factory<JdbcTypeHashBuilder> hashBuilderFactory = JdbcTypeDefaultHashBuilderFactory.INSTANCE;
+    /** Hash calculator.  */
+    protected JdbcTypeHasher hasher = JdbcTypeDefaultHasher.INSTANCE;
 
     /**
      * Get field value from object for use as query parameter.
@@ -215,14 +214,14 @@ public abstract class CacheAbstractJdbcStore<K, V> implements CacheStore<K, V>,
      * @param cacheName Cache name.
      * @param typeName Type name.
      * @param fields Fields descriptors.
+     * @param hashField Field names for hash code calculation.
      * @param loadColIdxs Select query columns index.
-     * @param key {@code true}
      * @param rs ResultSet.
      * @return Constructed object.
      * @throws CacheLoaderException If failed to construct cache object.
      */
     protected abstract <R> R buildObject(@Nullable String cacheName, String typeName,
-        JdbcTypeField[] fields, Map<String, Integer> loadColIdxs, boolean key, ResultSet rs)
+        JdbcTypeField[] fields, Collection<String> hashField, Map<String, Integer> loadColIdxs, ResultSet rs)
         throws CacheLoaderException;
 
     /**
@@ -525,8 +524,8 @@ public abstract class CacheAbstractJdbcStore<K, V> implements CacheStore<K, V>,
                     ResultSet rs = stmt.executeQuery();
 
                     while (rs.next()) {
-                        K key = buildObject(em.cacheName, em.keyType(), em.keyColumns(), em.loadColIdxs, true, rs);
-                        V val = buildObject(em.cacheName, em.valueType(), em.valueColumns(), em.loadColIdxs, false, rs);
+                        K key = buildObject(em.cacheName, em.keyType(), em.keyColumns(), em.keyCols, em.loadColIdxs, rs);
+                        V val = buildObject(em.cacheName, em.valueType(), em.valueColumns(), null, em.loadColIdxs, rs);
 
                         clo.apply(key, val);
                     }
@@ -557,58 +556,43 @@ public abstract class CacheAbstractJdbcStore<K, V> implements CacheStore<K, V>,
     }
 
     /**
-     * Object is a simple type.
-     *
-     * @param cls Class.
-     * @return {@code True} if object is a simple type.
-     */
-    protected static boolean simpleType(Class<?> cls) {
-        return (Number.class.isAssignableFrom(cls) || String.class.isAssignableFrom(cls) ||
-            java.util.Date.class.isAssignableFrom(cls) || Boolean.class.isAssignableFrom(cls) ||
-            UUID.class.isAssignableFrom(cls));
-    }
-
-    /**
      * @param cacheName Cache name to check mapping for.
-     * @param clsName Class name.
+     * @param typeName Type name.
      * @param fields Fields descriptors.
      * @throws CacheException If failed to check type metadata.
      */
-    private void checkMapping(@Nullable String cacheName, String clsName,
-        JdbcTypeField[] fields) throws CacheException {
+    private void checkMapping(@Nullable String cacheName, String typeName, JdbcTypeField[] fields) throws CacheException {
         try {
-            Class<?> cls = Class.forName(clsName);
-
-            if (simpleType(cls)) {
+            if (SIMPLE_TYPES.contains(typeName)) {
                 if (fields.length != 1)
                     throw new CacheException("More than one field for simple type [cache=" +  U.maskName(cacheName) +
-                        ", type=" + clsName + " ]");
+                        ", type=" + typeName + " ]");
 
                 JdbcTypeField field = fields[0];
 
                 if (field.getDatabaseFieldName() == null)
                     throw new CacheException("Missing database name in mapping description [cache=" +
-                        U.maskName(cacheName) + ", type=" + clsName + " ]");
+                        U.maskName(cacheName) + ", type=" + typeName + " ]");
 
-                field.setJavaFieldType(cls);
+                field.setJavaFieldType(Class.forName(typeName));
             }
             else
                 for (JdbcTypeField field : fields) {
                     if (field.getDatabaseFieldName() == null)
                         throw new CacheException("Missing database name in mapping description [cache=" +
-                            U.maskName(cacheName) + ", type=" + clsName + " ]");
+                            U.maskName(cacheName) + ", type=" + typeName + " ]");
 
                     if (field.getJavaFieldName() == null)
                         throw new CacheException("Missing field name in mapping description [cache=" +
-                            U.maskName(cacheName) + ", type=" + clsName + " ]");
+                            U.maskName(cacheName) + ", type=" + typeName + " ]");
 
                     if (field.getJavaFieldType() == null)
                         throw new CacheException("Missing field type in mapping description [cache=" +
-                            U.maskName(cacheName) + ", type=" + clsName + " ]");
+                            U.maskName(cacheName) + ", type=" + typeName + " ]");
                 }
         }
         catch (ClassNotFoundException e) {
-            throw new CacheException("Failed to find class: " + clsName, e);
+            throw new CacheException("Failed to find class: " + typeName, e);
         }
     }
 
@@ -736,10 +720,8 @@ public abstract class CacheAbstractJdbcStore<K, V> implements CacheStore<K, V>,
                         throw new CacheException("Key type must be unique in type metadata [cache=" +
                             U.maskName(cacheName) + ", key type=" + keyType + "]");
 
-                    if (!keepSerialized) {
-                        checkMapping(cacheName, keyType, type.getKeyFields());
-                        checkMapping(cacheName, valType, type.getValueFields());
-                    }
+                    checkMapping(cacheName, keyType, type.getKeyFields());
+                    checkMapping(cacheName, valType, type.getValueFields());
 
                     entryMappings.put(keyTypeId, new EntryMapping(cacheName, dialect, type));
                 }
@@ -885,7 +867,7 @@ public abstract class CacheAbstractJdbcStore<K, V> implements CacheStore<K, V>,
                 log.debug("Cache loaded from db: " +  U.maskName(cacheName));
         }
         catch (IgniteCheckedException e) {
-            throw new CacheLoaderException("Failed to load cache: " +  U.maskName(cacheName), e.getCause());
+            throw new CacheLoaderException("Failed to load cache: " + U.maskName(cacheName), e.getCause());
         }
         finally {
             U.shutdownNow(getClass(), pool, log);
@@ -915,7 +897,7 @@ public abstract class CacheAbstractJdbcStore<K, V> implements CacheStore<K, V>,
             ResultSet rs = stmt.executeQuery();
 
             if (rs.next())
-                return buildObject(em.cacheName, em.valueType(), em.valueColumns(), em.loadColIdxs, false, rs);
+                return buildObject(em.cacheName, em.valueType(), em.valueColumns(), null, em.loadColIdxs, rs);
         }
         catch (SQLException e) {
             throw new CacheLoaderException("Failed to load object [table=" + em.fullTableName() +
@@ -1583,21 +1565,21 @@ public abstract class CacheAbstractJdbcStore<K, V> implements CacheStore<K, V>,
     }
 
     /**
-     * Gets hash builder factory.
+     * Gets hash code calculator.
      *
-     * @return Hash builder factory.
+     * @return Hash code calculator.
      */
-    public Factory<JdbcTypeHashBuilder> getHashBuilderFactory() {
-        return hashBuilderFactory;
+    public JdbcTypeHasher getHasher() {
+        return hasher;
     }
 
     /**
-     * Sets hash builder factory..
+     * Sets hash code calculator.
      *
-     * @param hashBuilderFactory Hash builder factory.
+     * @param hasher Hash code calculator.
      */
-    public void setHashBuilderFactory(Factory<JdbcTypeHashBuilder> hashBuilderFactory) {
-        this.hashBuilderFactory = hashBuilderFactory;
+    public void setHasher(JdbcTypeHasher hasher) {
+        this.hasher = hasher;
     }
 
     /**
@@ -1903,8 +1885,8 @@ public abstract class CacheAbstractJdbcStore<K, V> implements CacheStore<K, V>,
                     colIdxs.put(meta.getColumnLabel(i), i);
 
                 while (rs.next()) {
-                    K1 key = buildObject(em.cacheName, em.keyType(), em.keyColumns(), colIdxs, true, rs);
-                    V1 val = buildObject(em.cacheName, em.valueType(), em.valueColumns(), colIdxs, false, rs);
+                    K1 key = buildObject(em.cacheName, em.keyType(), em.keyColumns(), em.keyCols, colIdxs, rs);
+                    V1 val = buildObject(em.cacheName, em.valueType(), em.valueColumns(), null, colIdxs, rs);
 
                     clo.apply(key, val);
                 }
@@ -1998,8 +1980,8 @@ public abstract class CacheAbstractJdbcStore<K, V> implements CacheStore<K, V>,
                 Map<K1, V1> entries = U.newHashMap(keys.size());
 
                 while (rs.next()) {
-                    K1 key = buildObject(em.cacheName, em.keyType(), em.keyColumns(), em.loadColIdxs, true, rs);
-                    V1 val = buildObject(em.cacheName, em.valueType(), em.valueColumns(), em.loadColIdxs, false, rs);
+                    K1 key = buildObject(em.cacheName, em.keyType(), em.keyColumns(), em.keyCols, em.loadColIdxs, rs);
+                    V1 val = buildObject(em.cacheName, em.valueType(), em.valueColumns(), null, em.loadColIdxs, rs);
 
                     entries.put(key, val);
                 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/00015227/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/CacheJdbcPojoStore.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/CacheJdbcPojoStore.java b/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/CacheJdbcPojoStore.java
index e29f6ca..04fb1db 100644
--- a/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/CacheJdbcPojoStore.java
+++ b/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/CacheJdbcPojoStore.java
@@ -18,6 +18,7 @@
 package org.apache.ignite.cache.store.jdbc;
 
 import org.apache.ignite.*;
+import org.apache.ignite.cache.IgniteObject;
 import org.apache.ignite.cache.store.*;
 import org.apache.ignite.configuration.*;
 import org.apache.ignite.internal.util.typedef.internal.*;
@@ -121,10 +122,10 @@ public class CacheJdbcPojoStore<K, V> extends CacheAbstractJdbcStore<K, V> {
 
     /** {@inheritDoc} */
     @Override protected <R> R buildObject(@Nullable String cacheName, String typeName,
-        JdbcTypeField[] fields, Map<String, Integer> loadColIdxs, boolean key, ResultSet rs)
+        JdbcTypeField[] fields, Collection<String> hashFields, Map<String, Integer> loadColIdxs, ResultSet rs)
         throws CacheLoaderException {
         return (R)(isKeepSerialized(cacheName, typeName)
-            ? buildPortableObject(cacheName, typeName, fields, loadColIdxs, key, rs)
+            ? buildPortableObject(cacheName, typeName, fields, hashFields, loadColIdxs, rs)
             : buildPojoObject(cacheName, typeName, fields, loadColIdxs, rs));
     }
 
@@ -200,14 +201,14 @@ public class CacheJdbcPojoStore<K, V> extends CacheAbstractJdbcStore<K, V> {
      * @param cacheName Cache name.
      * @param typeName Type name.
      * @param fields Fields descriptors.
+     * @param hashFields Collection of fields to build hash for.
      * @param loadColIdxs Select query columns index.
-     * @param hash If {@code true} then build object with hash.
      * @param rs ResultSet.
      * @return Constructed portable object.
      * @throws CacheLoaderException If failed to construct portable object.
      */
     protected Object buildPortableObject(String cacheName, String typeName, JdbcTypeField[] fields,
-        Map<String, Integer> loadColIdxs, boolean hash, ResultSet rs) throws CacheLoaderException {
+        Collection<String> hashFields, Map<String, Integer> loadColIdxs, ResultSet rs) throws CacheLoaderException {
         Map<String, IgniteBiTuple<Boolean, Integer>> cacheTypeIds = portableTypeIds.get(cacheName);
 
         if (cacheTypeIds == null)
@@ -235,34 +236,18 @@ public class CacheJdbcPojoStore<K, V> extends CacheAbstractJdbcStore<K, V> {
             else {
                 PortableBuilder builder = ignite.portables().builder(tuple.get2());
 
-                if (hash) {
-                    JdbcTypeHashBuilder hashBuilder = hashBuilderFactory.create();
-
-                    for (JdbcTypeField field : fields) {
-                        Integer colIdx = loadColIdxs.get(field.getDatabaseFieldName());
-
-                        String colName = field.getJavaFieldName();
-
-                        Object colVal = getColumnValue(rs, colIdx, field.getJavaFieldType());
-
-                        hashBuilder.toHash(colVal, typeName, colName);
+                for (JdbcTypeField field : fields) {
+                    Integer colIdx = loadColIdxs.get(field.getDatabaseFieldName());
 
-                        builder.setField(colName, colVal);
-                    }
+                    Object colVal = getColumnValue(rs, colIdx, field.getJavaFieldType());
 
-                    return builder.hashCode(hashBuilder.hash()).build();
+                    builder.setField(field.getJavaFieldName(), colVal);
                 }
-                 else {
-                    for (JdbcTypeField field : fields) {
-                        Integer colIdx = loadColIdxs.get(field.getDatabaseFieldName());
 
-                        Object colVal = getColumnValue(rs, colIdx, field.getJavaFieldType());
-
-                        builder.setField(field.getJavaFieldName(), colVal);
-                    }
+                if (hashFields != null)
+                    builder.hashCode(hasher.hashCode(new PortableBuilderWrapper(builder), hashFields));
 
-                    return builder.build();
-                }
+                return builder.build();
             }
         }
         catch (SQLException e) {
@@ -278,8 +263,8 @@ public class CacheJdbcPojoStore<K, V> extends CacheAbstractJdbcStore<K, V> {
      * @throws CacheException If failed to calculate type ID for given object.
      */
     @Override protected Object typeIdForObject(Object obj) throws CacheException {
-        if (obj instanceof PortableObject)
-            return ((PortableObject)obj).typeId();
+        if (obj instanceof IgniteObject)
+            return ((IgniteObject)obj).typeId();
 
         return obj.getClass();
     }
@@ -339,7 +324,6 @@ public class CacheJdbcPojoStore<K, V> extends CacheAbstractJdbcStore<K, V> {
 
                 typeMethods.put(keyType, new PojoMethodsCache(keyType, type.getKeyFields()));
 
-                // TODO: IGNITE-1753 fix if exists and merge getters if needed?
                 String valType = type.getValueType();
                 typeMethods.put(valType, new PojoMethodsCache(valType, type.getValueFields()));
             }
@@ -389,6 +373,43 @@ public class CacheJdbcPojoStore<K, V> extends CacheAbstractJdbcStore<K, V> {
     }
 
     /**
+     * Thin wrapper over {@link PortableBuilder} to use it as {@link IgniteObject} for hash code calculation.
+     */
+    private static class PortableBuilderWrapper implements IgniteObject {
+        /** Wrapped builder. */
+        private final PortableBuilder builder;
+
+        /**
+         * Create wrapper.
+         *
+         * @param builder Builder to wrap.
+         */
+        private PortableBuilderWrapper(final PortableBuilder builder) {
+            this.builder = builder;
+        }
+
+        /** {@inheritDoc} */
+        @Override public int typeId() {
+            return 0; // No need to wrap.
+        }
+
+        /** {@inheritDoc} */
+        @Nullable @Override public <F> F field(String fieldName) throws PortableException {
+            return builder.getField(fieldName);
+        }
+
+        /** {@inheritDoc} */
+        @Override public boolean hasField(String fieldName) {
+            return false; // No need to wrap.
+        }
+
+        /** {@inheritDoc} */
+        @Nullable @Override public <T> T deserialize() throws PortableException {
+            return null; // No need to wrap.
+        }
+    }
+
+    /**
      * POJO methods cache.
      */
     private static class PojoMethodsCache {
@@ -407,6 +428,18 @@ public class CacheJdbcPojoStore<K, V> extends CacheAbstractJdbcStore<K, V> {
         /** Cached getters for POJO object. */
         private Map<String, Method> setters;
 
+
+        /**
+         * Object is a simple type.
+         *
+         * @param cls Class.
+         * @return {@code True} if object is a simple type.
+         */
+        private boolean simpleType(Class<?> cls) {
+            return (Number.class.isAssignableFrom(cls) || String.class.isAssignableFrom(cls) ||
+                java.util.Date.class.isAssignableFrom(cls) || Boolean.class.isAssignableFrom(cls) ||
+                UUID.class.isAssignableFrom(cls));
+        }
         /**
          * POJO methods cache.
          *

http://git-wip-us.apache.org/repos/asf/ignite/blob/00015227/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/CacheJdbcPojoStoreConfiguration.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/CacheJdbcPojoStoreConfiguration.java b/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/CacheJdbcPojoStoreConfiguration.java
index 1361e46..2224904 100644
--- a/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/CacheJdbcPojoStoreConfiguration.java
+++ b/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/CacheJdbcPojoStoreConfiguration.java
@@ -17,10 +17,9 @@
 
 package org.apache.ignite.cache.store.jdbc;
 
-import javax.cache.configuration.Factory;
-import org.apache.ignite.cache.store.jdbc.dialect.*;
+import java.io.Serializable;
 
-import java.io.*;
+import org.apache.ignite.cache.store.jdbc.dialect.JdbcDialect;
 
 /**
  * JDBC POJO store configuration.
@@ -56,8 +55,8 @@ public class CacheJdbcPojoStoreConfiguration implements Serializable {
     /** Parallel load cache minimum threshold. If {@code 0} then load sequentially. */
     private int parallelLoadCacheMinThreshold = DFLT_PARALLEL_LOAD_CACHE_MINIMUM_THRESHOLD;
 
-    /** Factory for.  */
-    private Factory<JdbcTypeHashBuilder> hashBuilderFactory = JdbcTypeDefaultHashBuilderFactory.INSTANCE;
+    /** Hash calculator.  */
+    private JdbcTypeHasher hasher = JdbcTypeDefaultHasher.INSTANCE;
 
     /** Types that store could process. */
     private JdbcType[] types;
@@ -83,7 +82,7 @@ public class CacheJdbcPojoStoreConfiguration implements Serializable {
         maxWrtAttempts = cfg.getMaximumWriteAttempts();
         parallelLoadCacheMinThreshold = cfg.getParallelLoadCacheMinimumThreshold();
         types = cfg.getTypes();
-        hashBuilderFactory = cfg.getHashBuilderFactory();
+        hasher = cfg.getHasher();
     }
 
     /**
@@ -234,22 +233,22 @@ public class CacheJdbcPojoStoreConfiguration implements Serializable {
     }
 
     /**
-     * Gets hash builder factory.
+     * Gets hash code calculator.
      *
-     * @return Hash builder factory.
+     * @return Hash code calculator.
      */
-    public Factory<JdbcTypeHashBuilder> getHashBuilderFactory() {
-        return hashBuilderFactory;
+    public JdbcTypeHasher getHasher() {
+        return hasher;
     }
 
     /**
-     * Sets hash builder factory..
+     * Sets hash code calculator.
      *
-     * @param hashBuilderFactory Hash builder factory.
+     * @param hasher Hash code calculator.
      * @return {@code This} for chaining.
      */
-    public CacheJdbcPojoStoreConfiguration setHashBuilderFactory(Factory<JdbcTypeHashBuilder> hashBuilderFactory) {
-        this.hashBuilderFactory = hashBuilderFactory;
+    public CacheJdbcPojoStoreConfiguration setHasher(JdbcTypeHasher hasher) {
+        this.hasher = hasher;
 
         return this;
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/00015227/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/JdbcType.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/JdbcType.java b/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/JdbcType.java
index cee6263..93ab4b6 100644
--- a/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/JdbcType.java
+++ b/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/JdbcType.java
@@ -55,7 +55,7 @@ public class JdbcType implements Serializable {
     private boolean keepSerialized;
 
     /** Custom type hasher. */
-    private JdbcTypeHashBuilder hasher;
+    private JdbcTypeHasher hasher;
 
     /**
      * Empty constructor (all values are initialized to their defaults).

http://git-wip-us.apache.org/repos/asf/ignite/blob/00015227/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/JdbcTypeDefaultHashBuilder.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/JdbcTypeDefaultHashBuilder.java b/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/JdbcTypeDefaultHashBuilder.java
deleted file mode 100644
index e7330e8..0000000
--- a/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/JdbcTypeDefaultHashBuilder.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package org.apache.ignite.cache.store.jdbc;
-
-/**
- * Default implementation of {@link JdbcTypeHashBuilder}.
- *
- * This implementation ignores type and field names.
- */
-public class JdbcTypeDefaultHashBuilder implements JdbcTypeHashBuilder {
-    /** Hash code. */
-    private int hash = 0;
-
-    /** {@inheritDoc} */
-    @Override public int toHash(Object val, String typeName, String fieldName) {
-        hash = 31 * hash + (val != null ? val.hashCode() : 0);
-
-        return hash;
-    }
-
-    /** {@inheritDoc} */
-    @Override public int hash() {
-        return hash;
-    }
-}

http://git-wip-us.apache.org/repos/asf/ignite/blob/00015227/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/JdbcTypeDefaultHashBuilderFactory.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/JdbcTypeDefaultHashBuilderFactory.java b/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/JdbcTypeDefaultHashBuilderFactory.java
deleted file mode 100644
index 6dea4d1..0000000
--- a/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/JdbcTypeDefaultHashBuilderFactory.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package org.apache.ignite.cache.store.jdbc;
-
-import javax.cache.configuration.Factory;
-
-/**
- * Factory for creating default hash builder.
- */
-public class JdbcTypeDefaultHashBuilderFactory implements Factory<JdbcTypeHashBuilder> {
-    /** */
-    private static final long serialVersionUID = 0L;
-
-    /** Instance of factory for reuse. */
-    public final static JdbcTypeDefaultHashBuilderFactory INSTANCE = new JdbcTypeDefaultHashBuilderFactory();
-
-    /** {@inheritDoc} */
-    @Override public JdbcTypeHashBuilder create() {
-        return new JdbcTypeDefaultHashBuilder();
-    }
-}

http://git-wip-us.apache.org/repos/asf/ignite/blob/00015227/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/JdbcTypeDefaultHasher.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/JdbcTypeDefaultHasher.java b/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/JdbcTypeDefaultHasher.java
new file mode 100644
index 0000000..16038dd
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/JdbcTypeDefaultHasher.java
@@ -0,0 +1,31 @@
+package org.apache.ignite.cache.store.jdbc;
+
+import org.apache.ignite.cache.IgniteObject;
+
+import java.util.Collection;
+
+/**
+ * Default implementation of {@link JdbcTypeHasher}.
+ *
+ * This implementation ignores type and field names.
+ */
+public class JdbcTypeDefaultHasher implements JdbcTypeHasher {
+    /** */
+    private static final long serialVersionUID = 0L;
+
+    /** Singleton instance to use. */
+    public static final JdbcTypeHasher INSTANCE = new JdbcTypeDefaultHasher();
+
+    /** {@inheritDoc} */
+    @Override public int hashCode(IgniteObject obj, Collection<String> fields) {
+        int hash = 0;
+
+        for (String field : fields) {
+            Object val = obj.field(field);
+
+            hash = 31 * hash + (val != null ? val.hashCode() : 0);
+        }
+
+        return hash;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/00015227/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/JdbcTypeHashBuilder.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/JdbcTypeHashBuilder.java b/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/JdbcTypeHashBuilder.java
deleted file mode 100644
index 971ae06..0000000
--- a/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/JdbcTypeHashBuilder.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * 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.cache.store.jdbc;
-
-/**
- * API for implementing custom hashing logic for portable objects on server side.
- */
-public interface JdbcTypeHashBuilder {
-    /**
-     * Calculate hash code for specified value and field name.
-     *
-     * @param val Value to calculate hash code for.
-     * @param typeName Type name hash is calculating for.
-     * @param fieldName Field name that should participate in hash code calculation.
-     * @return Hash code.
-     */
-    public int toHash(Object val, String typeName, String fieldName);
-
-    /**
-     * @return Calculated hash code.
-     */
-    public int hash();
-}

http://git-wip-us.apache.org/repos/asf/ignite/blob/00015227/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/JdbcTypeHasher.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/JdbcTypeHasher.java b/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/JdbcTypeHasher.java
new file mode 100644
index 0000000..bb6bbf8
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/JdbcTypeHasher.java
@@ -0,0 +1,37 @@
+/*
+ * 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.cache.store.jdbc;
+
+import org.apache.ignite.cache.IgniteObject;
+
+import java.io.Serializable;
+import java.util.Collection;
+
+/**
+ * API for implementing custom hashing logic for portable objects on server side.
+ */
+public interface JdbcTypeHasher extends Serializable {
+    /**
+     * Calculate hash code for specified object and fields.
+     *
+     * @param obj Object to calculate hash code for.
+     * @param fields Collection of field names that should participate in hash code calculation.
+     * @return Hash code.
+     */
+    public int hashCode(IgniteObject obj, Collection<String> fields);
+}