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/02/17 09:59:39 UTC

[29/50] [abbrv] ignite git commit: IGNITE-4548 CacheJdbcStore: support mapping of enum types.

IGNITE-4548 CacheJdbcStore: support mapping of enum types.

(cherry picked from commit f1fca3a)


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

Branch: refs/heads/ignite-1.9
Commit: 92ceb7f71e3ec1856c69fa464c8a8c848314a27e
Parents: 9d9e61f
Author: Vasiliy Sisko <vs...@gridgain.com>
Authored: Fri Jan 20 16:22:24 2017 +0700
Committer: Andrey Novikov <an...@gridgain.com>
Committed: Wed Feb 1 17:43:17 2017 +0700

----------------------------------------------------------------------
 .../store/jdbc/CacheAbstractJdbcStore.java      | 12 +++++-
 .../store/jdbc/JdbcTypesDefaultTransformer.java | 19 +++++++++
 .../cache/store/jdbc/JdbcTypesTransformer.java  | 17 ++++++++
 .../CacheJdbcPojoStoreAbstractSelfTest.java     | 23 +++++++----
 .../store/jdbc/CacheJdbcPojoStoreTest.java      |  3 ++
 ...eJdbcStoreAbstractMultithreadedSelfTest.java | 17 ++++----
 .../ignite/cache/store/jdbc/model/Gender.java   | 41 ++++++++++++++++++++
 .../ignite/cache/store/jdbc/model/Person.java   | 31 ++++++++++++++-
 .../src/test/config/jdbc-pojo-store-builtin.xml |  8 ++++
 .../src/test/config/jdbc-pojo-store-obj.xml     |  8 ++++
 10 files changed, 162 insertions(+), 17 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/92ceb7f7/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 4bfd92b..e7ce526 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
@@ -80,6 +80,8 @@ import static java.sql.Statement.SUCCESS_NO_INFO;
 import static org.apache.ignite.cache.store.jdbc.CacheJdbcPojoStoreFactory.DFLT_BATCH_SIZE;
 import static org.apache.ignite.cache.store.jdbc.CacheJdbcPojoStoreFactory.DFLT_PARALLEL_LOAD_CACHE_MINIMUM_THRESHOLD;
 import static org.apache.ignite.cache.store.jdbc.CacheJdbcPojoStoreFactory.DFLT_WRITE_ATTEMPTS;
+import static org.apache.ignite.cache.store.jdbc.JdbcTypesTransformer.NUMERIC_TYPES;
+import static org.apache.ignite.cache.store.jdbc.JdbcTypesTransformer.NUMERIC_TYPES;
 
 /**
  * Implementation of {@link CacheStore} backed by JDBC.
@@ -1393,8 +1395,15 @@ public abstract class CacheAbstractJdbcStore<K, V> implements CacheStore<K, V>,
                             fieldVal = fieldVal.toString();
 
                             break;
+                        default:
+                            // No-op.
                     }
                 }
+                else if (field.getJavaFieldType().isEnum() && fieldVal instanceof Enum) {
+                    Enum val = (Enum)fieldVal;
+                    
+                    fieldVal = NUMERIC_TYPES.contains(field.getDatabaseFieldType()) ? val.ordinal() : val.name();
+                }
 
                 stmt.setObject(idx, fieldVal);
             }
@@ -2068,12 +2077,13 @@ public abstract class CacheAbstractJdbcStore<K, V> implements CacheStore<K, V>,
 
                 int idx = 1;
 
-                for (Object key : keys)
+                for (Object key : keys) {
                     for (JdbcTypeField field : em.keyColumns()) {
                         Object fieldVal = extractParameter(em.cacheName, em.keyType(), em.keyKind(), field.getJavaFieldName(), key);
 
                         fillParameter(stmt, idx++, field, fieldVal);
                     }
+                }
 
                 ResultSet rs = stmt.executeQuery();
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/92ceb7f7/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/JdbcTypesDefaultTransformer.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/JdbcTypesDefaultTransformer.java b/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/JdbcTypesDefaultTransformer.java
index c32eaa2..c387b77 100644
--- a/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/JdbcTypesDefaultTransformer.java
+++ b/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/JdbcTypesDefaultTransformer.java
@@ -114,6 +114,25 @@ public class JdbcTypesDefaultTransformer implements JdbcTypesTransformer {
                 return UUID.fromString((String)res);
         }
 
+        if (type.isEnum()) {
+            if (NUMERIC_TYPES.contains(rs.getMetaData().getColumnType(colIdx))) {
+                int ordinal = rs.getInt(colIdx);
+
+                Object[] values = type.getEnumConstants();
+
+                return rs.wasNull() || ordinal >= values.length ? null : values[ordinal];
+            }
+
+            String str = rs.getString(colIdx);
+
+            try {
+                return rs.wasNull() ? null : Enum.valueOf((Class<? extends Enum>) type, str.trim());
+            }
+            catch (IllegalArgumentException ignore) {
+                return null;
+            }
+        }
+
         return rs.getObject(colIdx);
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/92ceb7f7/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/JdbcTypesTransformer.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/JdbcTypesTransformer.java b/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/JdbcTypesTransformer.java
index 76fb00b..fc0bc88 100644
--- a/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/JdbcTypesTransformer.java
+++ b/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/JdbcTypesTransformer.java
@@ -20,11 +20,28 @@ package org.apache.ignite.cache.store.jdbc;
 import java.io.Serializable;
 import java.sql.ResultSet;
 import java.sql.SQLException;
+import java.util.List;
+import org.apache.ignite.internal.util.typedef.internal.U;
+
+import static java.sql.Types.BIGINT;
+import static java.sql.Types.DECIMAL;
+import static java.sql.Types.DOUBLE;
+import static java.sql.Types.FLOAT;
+import static java.sql.Types.INTEGER;
+import static java.sql.Types.NUMERIC;
+import static java.sql.Types.REAL;
+import static java.sql.Types.SMALLINT;
+import static java.sql.Types.TINYINT;
 
 /**
  * API for implementing custom mapping logic for loaded from store data.
  */
 public interface JdbcTypesTransformer extends Serializable {
+    /** Numeric types. */
+    public final List<Integer> NUMERIC_TYPES =
+        U.sealList(TINYINT, SMALLINT, INTEGER, BIGINT, REAL, FLOAT, DOUBLE, NUMERIC, DECIMAL);
+
+
     /**
      * Retrieves the value of the designated column in the current row of this <code>ResultSet</code> object and
      * will convert to the requested Java data type.

http://git-wip-us.apache.org/repos/asf/ignite/blob/92ceb7f7/modules/core/src/test/java/org/apache/ignite/cache/store/jdbc/CacheJdbcPojoStoreAbstractSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/cache/store/jdbc/CacheJdbcPojoStoreAbstractSelfTest.java b/modules/core/src/test/java/org/apache/ignite/cache/store/jdbc/CacheJdbcPojoStoreAbstractSelfTest.java
index 368a28e..1de44f7 100644
--- a/modules/core/src/test/java/org/apache/ignite/cache/store/jdbc/CacheJdbcPojoStoreAbstractSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/cache/store/jdbc/CacheJdbcPojoStoreAbstractSelfTest.java
@@ -30,6 +30,7 @@ import javax.cache.integration.CacheLoaderException;
 import org.apache.ignite.IgniteCache;
 import org.apache.ignite.cache.store.jdbc.dialect.H2Dialect;
 import org.apache.ignite.cache.store.jdbc.model.Person;
+import org.apache.ignite.cache.store.jdbc.model.Gender;
 import org.apache.ignite.cache.store.jdbc.model.PersonKey;
 import org.apache.ignite.configuration.CacheConfiguration;
 import org.apache.ignite.configuration.ConnectorConfiguration;
@@ -112,7 +113,8 @@ public abstract class CacheJdbcPojoStoreAbstractSelfTest extends GridCommonAbstr
             " id INTEGER PRIMARY KEY," +
             " org_id INTEGER," +
             " birthday DATE," +
-            " name VARCHAR(50))");
+            " name VARCHAR(50)," +
+            " gender VARCHAR(50))");
 
         conn.commit();
 
@@ -201,7 +203,8 @@ public abstract class CacheJdbcPojoStoreAbstractSelfTest extends GridCommonAbstr
             new JdbcTypeField(Types.INTEGER, "ID", Integer.class, "id"),
             new JdbcTypeField(Types.INTEGER, "ORG_ID", Integer.class, "orgId"),
             new JdbcTypeField(Types.DATE, "BIRTHDAY", Date.class, "birthday"),
-            new JdbcTypeField(Types.VARCHAR, "NAME", String.class, "name"));
+            new JdbcTypeField(Types.VARCHAR, "NAME", String.class, "name"),
+            new JdbcTypeField(Types.VARCHAR, "GENDER", Gender.class, "gender"));
 
         return storeTypes;
     }
@@ -260,7 +263,7 @@ public abstract class CacheJdbcPojoStoreAbstractSelfTest extends GridCommonAbstr
         conn.commit();
 
         PreparedStatement prnStmt = conn.prepareStatement(
-            "INSERT INTO Person(id, org_id, birthday, name) VALUES (?, ?, ?, ?)");
+            "INSERT INTO Person(id, org_id, birthday, name, gender) VALUES (?, ?, ?, ?, ?)");
 
         Random rnd = new Random();
 
@@ -269,6 +272,7 @@ public abstract class CacheJdbcPojoStoreAbstractSelfTest extends GridCommonAbstr
             prnStmt.setInt(2, i % 100);
             prnStmt.setDate(3, Date.valueOf(String.format("%d-%d-%d", 1970 + rnd.nextInt(50), 1 + rnd.nextInt(11), 1 + rnd.nextInt(27))));
             prnStmt.setString(4, "name" + i);
+            prnStmt.setString(5, Gender.random().toString());
 
             prnStmt.addBatch();
         }
@@ -319,7 +323,7 @@ public abstract class CacheJdbcPojoStoreAbstractSelfTest extends GridCommonAbstr
     protected void checkCacheLoadWithSql() {
         IgniteCache<Object, Object> c1 = grid().cache(CACHE_NAME);
 
-        c1.loadCache(null, "org.apache.ignite.cache.store.jdbc.model.PersonKey", "select id, org_id, name, birthday from Person");
+        c1.loadCache(null, "org.apache.ignite.cache.store.jdbc.model.PersonKey", "select id, org_id, name, birthday, gender from Person");
 
         assertEquals(PERSON_CNT, c1.size());
     }
@@ -397,7 +401,9 @@ public abstract class CacheJdbcPojoStoreAbstractSelfTest extends GridCommonAbstr
 
         Connection conn = getConnection();
         try {
-            PreparedStatement stmt = conn.prepareStatement("SELECT ID, ORG_ID, BIRTHDAY, NAME FROM PERSON WHERE ID = ?");
+            Random rnd = new Random();
+
+            PreparedStatement stmt = conn.prepareStatement("SELECT ID, ORG_ID, BIRTHDAY, NAME, GENDER FROM PERSON WHERE ID = ?");
 
             stmt.setInt(1, -1);
 
@@ -408,8 +414,9 @@ public abstract class CacheJdbcPojoStoreAbstractSelfTest extends GridCommonAbstr
             U.closeQuiet(rs);
 
             Date testDate = Date.valueOf("2001-05-05");
+            Gender testGender = Gender.random();
 
-            Person val = new Person(-1, -2, testDate, "Person-to-test-put-insert", 999);
+            Person val = new Person(-1, -2, testDate, "Person-to-test-put-insert", 999, testGender);
 
             Object key = builtinKeys ? Integer.valueOf(-1) : new PersonKey(-1);
 
@@ -424,6 +431,7 @@ public abstract class CacheJdbcPojoStoreAbstractSelfTest extends GridCommonAbstr
             assertEquals(-2, rs.getInt(2));
             assertEquals(testDate, rs.getDate(3));
             assertEquals("Person-to-test-put-insert", rs.getString(4));
+            assertEquals(testGender.toString(), rs.getString(5));
 
             assertFalse("Unexpected more data in result set", rs.next());
 
@@ -432,7 +440,7 @@ public abstract class CacheJdbcPojoStoreAbstractSelfTest extends GridCommonAbstr
             // Test put-update.
             testDate = Date.valueOf("2016-04-04");
 
-            c1.put(key, new Person(-1, -3, testDate, "Person-to-test-put-update", 999));
+            c1.put(key, new Person(-1, -3, testDate, "Person-to-test-put-update", 999, testGender));
 
             rs = stmt.executeQuery();
 
@@ -442,6 +450,7 @@ public abstract class CacheJdbcPojoStoreAbstractSelfTest extends GridCommonAbstr
             assertEquals(-3, rs.getInt(2));
             assertEquals(testDate, rs.getDate(3));
             assertEquals("Person-to-test-put-update", rs.getString(4));
+            assertEquals(testGender.toString(), rs.getString(5));
 
             assertFalse("Unexpected more data in result set", rs.next());
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/92ceb7f7/modules/core/src/test/java/org/apache/ignite/cache/store/jdbc/CacheJdbcPojoStoreTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/cache/store/jdbc/CacheJdbcPojoStoreTest.java b/modules/core/src/test/java/org/apache/ignite/cache/store/jdbc/CacheJdbcPojoStoreTest.java
index 4a0b1da..849cab7 100644
--- a/modules/core/src/test/java/org/apache/ignite/cache/store/jdbc/CacheJdbcPojoStoreTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/cache/store/jdbc/CacheJdbcPojoStoreTest.java
@@ -25,6 +25,7 @@ import java.sql.Timestamp;
 import java.sql.Types;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Random;
 import java.util.UUID;
 import java.util.concurrent.ConcurrentLinkedQueue;
 import javax.cache.integration.CacheWriterException;
@@ -233,6 +234,8 @@ public class CacheJdbcPojoStoreTest extends GridAbstractCacheStoreSelfTest<Cache
     public void testLoadCache() throws Exception {
         Connection conn = store.openConnection(false);
 
+        Random rnd = new Random();
+
         PreparedStatement orgStmt = conn.prepareStatement("INSERT INTO Organization(id, name, city) VALUES (?, ?, ?)");
 
         for (int i = 0; i < ORGANIZATION_CNT; i++) {

http://git-wip-us.apache.org/repos/asf/ignite/blob/92ceb7f7/modules/core/src/test/java/org/apache/ignite/cache/store/jdbc/CacheJdbcStoreAbstractMultithreadedSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/cache/store/jdbc/CacheJdbcStoreAbstractMultithreadedSelfTest.java b/modules/core/src/test/java/org/apache/ignite/cache/store/jdbc/CacheJdbcStoreAbstractMultithreadedSelfTest.java
index e831445..f1a321b 100644
--- a/modules/core/src/test/java/org/apache/ignite/cache/store/jdbc/CacheJdbcStoreAbstractMultithreadedSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/cache/store/jdbc/CacheJdbcStoreAbstractMultithreadedSelfTest.java
@@ -33,6 +33,7 @@ import java.util.concurrent.Callable;
 import org.apache.ignite.IgniteCache;
 import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.cache.CacheTypeMetadata;
+import org.apache.ignite.cache.store.jdbc.model.Gender;
 import org.apache.ignite.cache.store.jdbc.model.Organization;
 import org.apache.ignite.cache.store.jdbc.model.OrganizationKey;
 import org.apache.ignite.cache.store.jdbc.model.Person;
@@ -208,7 +209,7 @@ public abstract class CacheJdbcStoreAbstractMultithreadedSelfTest<T extends Cach
                         cache.put(new OrganizationKey(id), new Organization(id, "Name" + id, "City" + id));
                     else
                         cache.put(new PersonKey(id), new Person(id, rnd.nextInt(),
-                            new Date(System.currentTimeMillis()), "Name" + id, 1));
+                            new Date(System.currentTimeMillis()), "Name" + id, 1, Gender.random()));
                 }
 
                 return null;
@@ -228,7 +229,7 @@ public abstract class CacheJdbcStoreAbstractMultithreadedSelfTest<T extends Cach
                         cache.putIfAbsent(new OrganizationKey(id), new Organization(id, "Name" + id, "City" + id));
                     else
                         cache.putIfAbsent(new PersonKey(id), new Person(id, rnd.nextInt(),
-                            new Date(System.currentTimeMillis()), "Name" + id, i));
+                            new Date(System.currentTimeMillis()), "Name" + id, i, Gender.random()));
                 }
 
                 return null;
@@ -268,7 +269,7 @@ public abstract class CacheJdbcStoreAbstractMultithreadedSelfTest<T extends Cach
                             map.put(new OrganizationKey(id), new Organization(id, "Name" + id, "City" + id));
                         else
                             map.put(new PersonKey(id), new Person(id, rnd.nextInt(),
-                                new Date(System.currentTimeMillis()), "Name" + id, 1));
+                                new Date(System.currentTimeMillis()), "Name" + id, 1, Gender.random()));
                     }
 
                     IgniteCache<Object, Object> cache = jcache();
@@ -294,11 +295,11 @@ public abstract class CacheJdbcStoreAbstractMultithreadedSelfTest<T extends Cach
 
                     try (Transaction tx = grid().transactions().txStart()) {
                         cache.put(new PersonKey(1), new Person(1, rnd.nextInt(),
-                            new Date(System.currentTimeMillis()), "Name" + 1, 1));
+                            new Date(System.currentTimeMillis()), "Name" + 1, 1, Gender.random()));
                         cache.put(new PersonKey(2), new Person(2, rnd.nextInt(),
-                            new Date(System.currentTimeMillis()), "Name" + 2, 2));
+                            new Date(System.currentTimeMillis()), "Name" + 2, 2, Gender.random()));
                         cache.put(new PersonKey(3), new Person(3, rnd.nextInt(),
-                            new Date(System.currentTimeMillis()), "Name" + 3, 3));
+                            new Date(System.currentTimeMillis()), "Name" + 3, 3, Gender.random()));
 
                         cache.get(new PersonKey(1));
                         cache.get(new PersonKey(4));
@@ -306,9 +307,9 @@ public abstract class CacheJdbcStoreAbstractMultithreadedSelfTest<T extends Cach
                         Map<PersonKey, Person> map =  U.newHashMap(2);
 
                         map.put(new PersonKey(5), new Person(5, rnd.nextInt(),
-                            new Date(System.currentTimeMillis()), "Name" + 5, 5));
+                            new Date(System.currentTimeMillis()), "Name" + 5, 5, Gender.random()));
                         map.put(new PersonKey(6), new Person(6, rnd.nextInt(),
-                            new Date(System.currentTimeMillis()), "Name" + 6, 6));
+                            new Date(System.currentTimeMillis()), "Name" + 6, 6, Gender.random()));
 
                         cache.putAll(map);
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/92ceb7f7/modules/core/src/test/java/org/apache/ignite/cache/store/jdbc/model/Gender.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/cache/store/jdbc/model/Gender.java b/modules/core/src/test/java/org/apache/ignite/cache/store/jdbc/model/Gender.java
new file mode 100644
index 0000000..8ddb0e2
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/cache/store/jdbc/model/Gender.java
@@ -0,0 +1,41 @@
+/*
+ * 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.model;
+
+import java.io.Serializable;
+import java.util.Random;
+
+/**
+ * Person gender enum.
+ */
+public enum Gender implements Serializable {
+    /** */
+    MALE,
+    /** */
+    FEMALE;
+
+    /** */
+    private static final Random RAND = new Random();
+
+    /**
+     * Used for testing purposes.
+     */
+    public static Gender random() {
+        return values()[RAND.nextInt(values().length)];
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/92ceb7f7/modules/core/src/test/java/org/apache/ignite/cache/store/jdbc/model/Person.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/cache/store/jdbc/model/Person.java b/modules/core/src/test/java/org/apache/ignite/cache/store/jdbc/model/Person.java
index 52ddfc8..89258b4 100644
--- a/modules/core/src/test/java/org/apache/ignite/cache/store/jdbc/model/Person.java
+++ b/modules/core/src/test/java/org/apache/ignite/cache/store/jdbc/model/Person.java
@@ -44,6 +44,9 @@ public class Person implements Serializable {
     /** Value for salary. */
     private Integer salary;
 
+    /** Value of person gender. */
+    private Gender gender;
+
     /**
      * Empty constructor.
      */
@@ -59,13 +62,15 @@ public class Person implements Serializable {
         Integer orgId,
         Date birthday,
         String name,
-        Integer salary
+        Integer salary,
+        Gender gender
     ) {
         this.id = id;
         this.orgId = orgId;
         this.birthday = birthday;
         this.name = name;
         this.salary = salary;
+        this.gender = gender;
     }
 
     /**
@@ -159,6 +164,24 @@ public class Person implements Serializable {
         this.salary = salary;
     }
 
+    /**
+     * Gets gender.
+     *
+     * @return Gender.
+     */
+    public Gender getGender() {
+        return gender;
+    }
+
+    /**
+     * Sets gender.
+     *
+     * @param gender New value for gender.
+     */
+    public void setGender(Gender gender) {
+        this.gender = gender;
+    }
+
     /** {@inheritDoc} */
     @Override public boolean equals(Object o) {
         if (this == o)
@@ -178,6 +201,9 @@ public class Person implements Serializable {
         if (name != null ? !name.equals(that.name) : that.name != null)
             return false;
 
+        if (gender != null ? !gender.equals(that.gender) : that.gender != null)
+            return false;
+
         return true;
     }
 
@@ -189,6 +215,8 @@ public class Person implements Serializable {
 
         res = 31 * res + (name != null ? name.hashCode() : 0);
 
+        res = 31 * res + (gender != null ? gender.hashCode() : 0);
+
         return res;
     }
 
@@ -198,6 +226,7 @@ public class Person implements Serializable {
             ", orgId=" + orgId +
             ", birthday=" + (birthday == null ? null : birthday.getTime()) +
             ", name=" + name +
+            ", gender=" + gender +
             "]";
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/92ceb7f7/modules/spring/src/test/config/jdbc-pojo-store-builtin.xml
----------------------------------------------------------------------
diff --git a/modules/spring/src/test/config/jdbc-pojo-store-builtin.xml b/modules/spring/src/test/config/jdbc-pojo-store-builtin.xml
index dfaf828..bfb109c 100644
--- a/modules/spring/src/test/config/jdbc-pojo-store-builtin.xml
+++ b/modules/spring/src/test/config/jdbc-pojo-store-builtin.xml
@@ -151,6 +151,14 @@
                                                     <property name="javaFieldName" value="orgId"/>
                                                     <property name="javaFieldType" value="java.lang.Integer"/>
                                                 </bean>
+                                                <bean class="org.apache.ignite.cache.store.jdbc.JdbcTypeField">
+                                                    <property name="databaseFieldName" value="GENDER"/>
+                                                    <property name="databaseFieldType">
+                                                        <util:constant static-field="java.sql.Types.VARCHAR"/>
+                                                    </property>
+                                                    <property name="javaFieldName" value="gender"/>
+                                                    <property name="javaFieldType" value="org.apache.ignite.cache.store.jdbc.model.Gender"/>
+                                                </bean>
                                             </list>
                                         </property>
                                     </bean>

http://git-wip-us.apache.org/repos/asf/ignite/blob/92ceb7f7/modules/spring/src/test/config/jdbc-pojo-store-obj.xml
----------------------------------------------------------------------
diff --git a/modules/spring/src/test/config/jdbc-pojo-store-obj.xml b/modules/spring/src/test/config/jdbc-pojo-store-obj.xml
index 9bc9977..40a14dc 100644
--- a/modules/spring/src/test/config/jdbc-pojo-store-obj.xml
+++ b/modules/spring/src/test/config/jdbc-pojo-store-obj.xml
@@ -151,6 +151,14 @@
                                                     <property name="javaFieldName" value="orgId"/>
                                                     <property name="javaFieldType" value="java.lang.Integer"/>
                                                 </bean>
+                                                <bean class="org.apache.ignite.cache.store.jdbc.JdbcTypeField">
+                                                    <property name="databaseFieldName" value="GENDER"/>
+                                                    <property name="databaseFieldType">
+                                                        <util:constant static-field="java.sql.Types.VARCHAR"/>
+                                                    </property>
+                                                    <property name="javaFieldName" value="gender"/>
+                                                    <property name="javaFieldType" value="org.apache.ignite.cache.store.jdbc.model.Gender"/>
+                                                </bean>
                                             </list>
                                         </property>
                                     </bean>