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/02/01 15:48:10 UTC

[2/2] incubator-ignite git commit: # IGNITE-32: reworked db metadata parser to use dialect.

# IGNITE-32: reworked db metadata parser to use dialect.


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

Branch: refs/heads/ignite-32
Commit: 7c1a29be35bd1d125a0dfec5a87af78c87a64b20
Parents: fe50f54
Author: AKuznetsov <ak...@gridgain.com>
Authored: Sun Feb 1 21:48:01 2015 +0700
Committer: AKuznetsov <ak...@gridgain.com>
Committed: Sun Feb 1 21:48:01 2015 +0700

----------------------------------------------------------------------
 .../query/CacheQueryTableColumnMetadata.java    | 143 +++++++++
 .../cache/query/CacheQueryTableMetadata.java    | 134 ++++++++
 .../cache/query/CacheQueryTypeDescriptor.java   | 135 --------
 .../cache/query/CacheQueryTypeMetadata.java     | 143 +++------
 .../ignite/cache/store/jdbc/JdbcCacheStore.java |  97 +++---
 .../cache/store/jdbc/JdbcPojoCacheStore.java    |  20 +-
 .../core/src/test/config/store/jdbc/Ignite.xml  |  16 +-
 modules/schema-load/pom.xml                     |   1 +
 .../ignite/schema/generator/XmlGenerator.java   | 122 ++++----
 .../ignite/schema/model/PojoDescriptor.java     | 248 ++++++++++-----
 .../apache/ignite/schema/model/PojoField.java   | 162 ++++------
 .../schema/parser/DatabaseMetadataParser.java   | 305 +++++--------------
 .../apache/ignite/schema/parser/DbColumn.java   |  76 +++++
 .../apache/ignite/schema/parser/DbIndex.java    |  39 +++
 .../apache/ignite/schema/parser/DbTable.java    |  98 ++++++
 .../parser/dialect/DB2MetadataDialect.java      |  30 ++
 .../parser/dialect/DatabaseMetadataDialect.java |  45 +++
 .../parser/dialect/JdbcMetadataDialect.java     | 115 +++++++
 .../parser/dialect/OracleMetadataDialect.java   |  33 ++
 .../org/apache/ignite/schema/ui/MessageBox.java |  12 +-
 .../apache/ignite/schema/ui/SchemaLoadApp.java  |  38 +--
 .../schema/load/BaseSchemaLoaderSelfTest.java   |  13 +-
 .../load/generator/PojoGeneratorSelfTest.java   |   2 +-
 .../load/generator/XmlGeneratorSelfTest.java    |  12 +-
 .../apache/ignite/schema/load/model/Ignite.xml  |  64 ++--
 .../load/parser/DbMetadataParserSelfTest.java   |   4 +-
 26 files changed, 1261 insertions(+), 846 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/7c1a29be/modules/core/src/main/java/org/apache/ignite/cache/query/CacheQueryTableColumnMetadata.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/cache/query/CacheQueryTableColumnMetadata.java b/modules/core/src/main/java/org/apache/ignite/cache/query/CacheQueryTableColumnMetadata.java
new file mode 100644
index 0000000..059cc8b
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/cache/query/CacheQueryTableColumnMetadata.java
@@ -0,0 +1,143 @@
+/*
+ * 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.query;
+
+import org.apache.ignite.internal.util.typedef.internal.*;
+
+/**
+ * Database table column metadata.
+ */
+public class CacheQueryTableColumnMetadata {
+    /** Column name in database. */
+    private String dbName;
+
+    /** Column JDBC type in database. */
+    private int dbType;
+
+    /** Column name in database. */
+    private String javaName;
+
+    /** Corresponding java type. */
+    private Class<?> javaType;
+
+    /**
+     * Default constructor.
+     */
+    public CacheQueryTableColumnMetadata() {
+        // No-op.
+    }
+
+    /**
+     * @param dbName Column name in database.
+     * @param dbType Column JDBC type in database.
+     * @param javaName Field name in java object.
+     * @param javaType Field java type.
+     */
+    public CacheQueryTableColumnMetadata(String javaName, Class<?> javaType, String dbName, int dbType) {
+        this.dbName = dbName;
+        this.dbType = dbType;
+        this.javaName = javaName;
+        this.javaType = javaType;
+    }
+
+    /**
+     * @return Column name in database.
+     */
+    public String getDbName() {
+        return dbName;
+    }
+
+    /**
+     * @param dbName Column name in database.
+     */
+    public void setDbName(String dbName) {
+        this.dbName = dbName;
+    }
+
+    /**
+     * @return Column JDBC type in database.
+     */
+    public int getDbType() {
+        return dbType;
+    }
+
+    /**
+     * @param dbType Column JDBC type in database.
+     */
+    public void setDbType(int dbType) {
+        this.dbType = dbType;
+    }
+
+    /**
+     * @return Field name in java object.
+     */
+    public String getJavaName() {
+        return javaName;
+    }
+
+    /**
+     * @param javaName Field name in java object.
+     */
+    public void setJavaName(String javaName) {
+        this.javaName = javaName;
+    }
+
+    /**
+     * @return Field java type.
+     */
+    public Class<?> getJavaType() {
+        return javaType;
+    }
+
+    /**
+     * @param javaType Corresponding java type.
+     */
+    public void setJavaType(Class<?> javaType) {
+        this.javaType = javaType;
+    }
+
+     /** {@inheritDoc} */
+    @Override public boolean equals(Object o) {
+        if (this == o)
+            return true;
+
+        if (!(o instanceof CacheQueryTableColumnMetadata))
+            return false;
+
+        CacheQueryTableColumnMetadata that = (CacheQueryTableColumnMetadata)o;
+
+        return javaName.equals(that.javaName) && dbName.equals(that.dbName) &&
+            javaType == that.javaType && dbType == that.dbType;
+    }
+
+    /** {@inheritDoc} */
+    @Override public int hashCode() {
+        int res = dbName.hashCode();
+
+        res = 31 * res + dbType;
+        res = 31 * res + javaName.hashCode();
+        res = 31 * res + javaType.hashCode();
+
+        return res;
+    }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        return S.toString(CacheQueryTableColumnMetadata.class, this);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/7c1a29be/modules/core/src/main/java/org/apache/ignite/cache/query/CacheQueryTableMetadata.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/cache/query/CacheQueryTableMetadata.java b/modules/core/src/main/java/org/apache/ignite/cache/query/CacheQueryTableMetadata.java
new file mode 100644
index 0000000..63436cb
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/cache/query/CacheQueryTableMetadata.java
@@ -0,0 +1,134 @@
+/*
+ * 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.query;
+
+import org.apache.ignite.internal.util.tostring.*;
+
+import java.util.*;
+
+/**
+ * Database table metadata.
+ */
+public class CacheQueryTableMetadata {
+    /** Schema name in database. */
+    private String schema;
+
+    /** Table name in database. */
+    private String tbl;
+
+    /** Key columns. */
+    @GridToStringInclude
+    private Collection<CacheQueryTableColumnMetadata> keyCols;
+
+    /** Value columns . */
+    @GridToStringInclude
+    private Collection<CacheQueryTableColumnMetadata> valCols;
+
+    /**
+     * Default constructor.
+     */
+    public CacheQueryTableMetadata() {
+        keyCols = new ArrayList<>();
+        valCols = new ArrayList<>();
+    }
+
+    /**
+     * Copy constructor.
+     *
+     * @param src Source table metadata.
+     */
+    public CacheQueryTableMetadata(CacheQueryTableMetadata src) {
+        schema = src.getSchema();
+        tbl = src.getTableName();
+
+        keyCols = new ArrayList<>(src.getKeyColumns());
+        valCols = new ArrayList<>(src.getValueColumns());
+    }
+
+    /**
+     * Gets database schema name.
+     *
+     * @return Schema name.
+     */
+    public String getSchema() {
+        return schema;
+    }
+
+    /**
+     * Sets database schema name.
+     *
+     * @param schema Schema name.
+     */
+    public void setSchema(String schema) {
+        this.schema = schema;
+    }
+
+    /**
+     * Gets table name in database.
+     *
+     * @return Table name in database.
+     */
+    public String getTableName() {
+        return tbl;
+    }
+
+    /**
+     * Table name in database.
+     *
+     * @param tbl Table name in database.
+     */
+    public void setTableName(String tbl) {
+        this.tbl = tbl;
+    }
+
+    /**
+     * Gets key columns.
+     *
+     * @return Key columns.
+     */
+    public Collection<CacheQueryTableColumnMetadata> getKeyColumns() {
+        return keyCols;
+    }
+
+    /**
+     * Sets key columns.
+     *
+     * @param keyCols New key columns.
+     */
+    public void setKeyColumns(Collection<CacheQueryTableColumnMetadata> keyCols) {
+        this.keyCols = keyCols;
+    }
+
+    /**
+     * Gets value columns.
+     *
+     * @return Value columns.
+     */
+    public Collection<CacheQueryTableColumnMetadata> getValueColumns() {
+        return valCols;
+    }
+
+    /**
+     * Sets value columns.
+     *
+     * @param valCols New value columns.
+     */
+    public void setValueColumnbs(Collection<CacheQueryTableColumnMetadata> valCols) {
+        this.valCols = valCols;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/7c1a29be/modules/core/src/main/java/org/apache/ignite/cache/query/CacheQueryTypeDescriptor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/cache/query/CacheQueryTypeDescriptor.java b/modules/core/src/main/java/org/apache/ignite/cache/query/CacheQueryTypeDescriptor.java
deleted file mode 100644
index 9e660cb..0000000
--- a/modules/core/src/main/java/org/apache/ignite/cache/query/CacheQueryTypeDescriptor.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/* @java.file.header */
-
-/*  _________        _____ __________________        _____
- *  __  ____/___________(_)______  /__  ____/______ ____(_)_______
- *  _  / __  __  ___/__  / _  __  / _  / __  _  __ `/__  / __  __ \
- *  / /_/ /  _  /    _  /  / /_/ /  / /_/ /  / /_/ / _  /  _  / / /
- *  \____/   /_/     /_/   \_,__/   \____/   \__,_/  /_/   /_/ /_/
- */
-
-package org.apache.ignite.cache.query;
-
-import org.apache.ignite.internal.util.typedef.internal.*;
-
-/**
- * Type descriptor for field in java and database.
- */
-public class CacheQueryTypeDescriptor {
-    /** Column name in database. */
-    private String javaName;
-
-    /** Corresponding java type. */
-    private Class<?> javaType;
-
-    /** Column name in database. */
-    private String dbName;
-
-    /** Column JDBC type in database. */
-    private int dbType;
-
-    /**
-     * Default constructor.
-     */
-    public CacheQueryTypeDescriptor() {
-        // No-op.
-    }
-
-    /**
-     * @param javaName Field name in java object.
-     * @param javaType Field java type.
-     * @param dbName Column name in database.
-     * @param dbType Column JDBC type in database.
-     */
-    public CacheQueryTypeDescriptor(String javaName, Class<?> javaType, String dbName, int dbType) {
-        this.javaName = javaName;
-        this.javaType = javaType;
-        this.dbName = dbName;
-        this.dbType = dbType;
-    }
-
-    /**
-     * @return Field name in java object.
-     */
-    public String getJavaName() {
-        return javaName;
-    }
-
-    /**
-     * @param javaName Field name in java object.
-     */
-    public void setJavaName(String javaName) {
-        this.javaName = javaName;
-    }
-
-    /**
-     * @return Field java type.
-     */
-    public Class<?> getJavaType() {
-        return javaType;
-    }
-
-    /**
-     * @param javaType Corresponding java type.
-     */
-    public void setJavaType(Class<?> javaType) {
-        this.javaType = javaType;
-    }
-
-    /**
-     * @return Column name in database.
-     */
-    public String getDbName() {
-        return dbName;
-    }
-
-    /**
-     * @param dbName Column name in database.
-     */
-    public void setDbName(String dbName) {
-        this.dbName = dbName;
-    }
-
-    /**
-     * @return Column JDBC type in database.
-     */
-    public int getDbType() {
-        return dbType;
-    }
-
-    /**
-     * @param dbType Column JDBC type in database.
-     */
-    public void setDbType(int dbType) {
-        this.dbType = dbType;
-    }
-
-     /** {@inheritDoc} */
-    @Override public boolean equals(Object o) {
-        if (this == o)
-            return true;
-
-        if (!(o instanceof CacheQueryTypeDescriptor))
-            return false;
-
-        CacheQueryTypeDescriptor that = (CacheQueryTypeDescriptor)o;
-
-        return javaName.equals(that.javaName) && dbName.equals(that.dbName) &&
-            javaType == that.javaType && dbType == that.dbType;
-    }
-
-    /** {@inheritDoc} */
-    @Override public int hashCode() {
-        int res = javaName.hashCode();
-
-        res = 31 * res + dbName.hashCode();
-        res = 31 * res + javaType.hashCode();
-        res = 31 * res + dbType;
-
-        return res;
-    }
-
-    /** {@inheritDoc} */
-    @Override public String toString() {
-        return S.toString(CacheQueryTypeDescriptor.class, this);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/7c1a29be/modules/core/src/main/java/org/apache/ignite/cache/query/CacheQueryTypeMetadata.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/cache/query/CacheQueryTypeMetadata.java b/modules/core/src/main/java/org/apache/ignite/cache/query/CacheQueryTypeMetadata.java
index 4a1d8eb..775fde9 100644
--- a/modules/core/src/main/java/org/apache/ignite/cache/query/CacheQueryTypeMetadata.java
+++ b/modules/core/src/main/java/org/apache/ignite/cache/query/CacheQueryTypeMetadata.java
@@ -27,25 +27,14 @@ import java.util.*;
  * Cache query type metadata.
  */
 public class CacheQueryTypeMetadata {
-    /** Type name, e.g. class name. */
-    private String type;
-
-    /** Schema name in database. */
-    private String schema;
-
-    /** Table name in database. */
-    private String tbl;
-
-    /** Key class. */
+    /** Key class used to store value in cache. */
     private String keyType;
 
-    /** Type descriptors. */
-    @GridToStringInclude
-    private Collection<CacheQueryTypeDescriptor> keyDescs;
+    /** Type name, e.g. class name. */
+    private String valType;
 
-    /** Type descriptors. */
-    @GridToStringInclude
-    private Collection<CacheQueryTypeDescriptor> valDescs;
+    /** Database table metadata.*/
+    private CacheQueryTableMetadata tblMeta;
 
     /** Fields to be queried, in addition to indexed fields. */
     @GridToStringInclude
@@ -71,9 +60,7 @@ public class CacheQueryTypeMetadata {
      * Default constructor.
      */
     public CacheQueryTypeMetadata() {
-        keyDescs = new ArrayList<>();
-
-        valDescs = new ArrayList<>();
+        tblMeta = new CacheQueryTableMetadata();
 
         qryFlds = new LinkedHashMap<>();
 
@@ -87,90 +74,27 @@ public class CacheQueryTypeMetadata {
     }
 
     /**
-     *
+     * Copy constructor.
      */
-    public CacheQueryTypeMetadata( CacheQueryTypeMetadata src) {
-        type = src.getType();
+    public CacheQueryTypeMetadata(CacheQueryTypeMetadata src) {
         keyType = src.getKeyType();
 
-        schema = src.getSchema();
-        tbl = src.getTableName();
+        valType = src.getType();
 
-        keyDescs = new ArrayList<>(src.getKeyDescriptors());
-        valDescs = new ArrayList<>(src.getValueDescriptors());
+        tblMeta = new CacheQueryTableMetadata(src.getTableMetadata());
 
         qryFlds = new LinkedHashMap<>(src.getQueryFields());
+
         ascFlds = new LinkedHashMap<>(src.getAscendingFields());
+
         descFlds = new LinkedHashMap<>(src.getDescendingFields());
+
         txtFlds = new LinkedHashSet<>(src.getTextFields());
 
         grps = new LinkedHashMap<>(src.getGroups());
     }
 
     /**
-     * Gets type (e.g. class name).
-     *
-     * @return Type name.
-     */
-    public String getType() {
-        return type;
-    }
-
-    /**
-     * Sets type.
-     *
-     * @param cls Type class.
-     */
-    public void setType(Class<?> cls) {
-        setType(cls.getName());
-    }
-
-    /**
-     * Sets type.
-     *
-     * @param type Type name.
-     */
-    public void setType(String type) {
-        this.type = type;
-    }
-
-    /**
-     * Gets database schema name.
-     *
-     * @return Schema name.
-     */
-    public String getSchema() {
-        return schema;
-    }
-
-    /**
-     * Sets database schema name.
-     *
-     * @param schema Schema name.
-     */
-    public void setSchema(String schema) {
-        this.schema = schema;
-    }
-
-    /**
-     * Gets table name in database.
-     *
-     * @return Table name in database.
-     */
-    public String getTableName() {
-        return tbl;
-    }
-
-    /**
-     * Table name in database.
-     *
-     * @param tbl Table name in database.
-     */
-    public void setTableName(String tbl) {
-        this.tbl = tbl;
-    }
-
-    /**
      * Gets key type.
      *
      * @return Key type.
@@ -189,39 +113,48 @@ public class CacheQueryTypeMetadata {
     }
 
     /**
-     * Gets key fields type descriptors.
+     * Gets type (e.g. class name).
+     *
+     * @return Type name.
+     */
+    public String getType() {
+        return valType;
+    }
+
+    /**
+     * Sets type.
      *
-     * @return Key fields type descriptors.
+     * @param cls Type class.
      */
-    public Collection<CacheQueryTypeDescriptor> getKeyDescriptors() {
-        return keyDescs;
+    public void setType(Class<?> cls) {
+        setType(cls.getName());
     }
 
     /**
-     * Sets key fields type descriptors.
+     * Sets type.
      *
-     * @param keyDescs Key fields type descriptors.
+     * @param type Type name.
      */
-    public void setKeyDescriptors(Collection<CacheQueryTypeDescriptor> keyDescs) {
-        this.keyDescs = keyDescs;
+    public void setType(String type) {
+        valType = type;
     }
 
     /**
-     * Gets value fields type descriptors.
+     * Gets table metadata.
      *
-     * @return Key value type descriptors.
+     * @return table metadata.
      */
-    public Collection<CacheQueryTypeDescriptor> getValueDescriptors() {
-        return valDescs;
+    public CacheQueryTableMetadata getTableMetadata() {
+        return tblMeta;
     }
 
     /**
-     * Sets value fields type descriptors.
+     * Sets table metadata.
      *
-     * @param valDescs Value fields type descriptors.
+     * @param tblMeta New table metadata.
      */
-    public void setValueDescriptors(Collection<CacheQueryTypeDescriptor> valDescs) {
-        this.valDescs = valDescs;
+    public void setTableMetadata(CacheQueryTableMetadata tblMeta) {
+        this.tblMeta = tblMeta;
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/7c1a29be/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/JdbcCacheStore.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/JdbcCacheStore.java b/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/JdbcCacheStore.java
index 7fd7494..b6887f0 100644
--- a/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/JdbcCacheStore.java
+++ b/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/JdbcCacheStore.java
@@ -154,7 +154,7 @@ public abstract class JdbcCacheStore<K, V> extends CacheStore<K, V> {
      * @param rs ResultSet.
      * @return Constructed object.
      */
-    protected abstract <R> R buildObject(String typeName, Collection<CacheQueryTypeDescriptor> fields, ResultSet rs)
+    protected abstract <R> R buildObject(String typeName, Collection<CacheQueryTableColumnMetadata> fields, ResultSet rs)
         throws CacheLoaderException;
 
     /**
@@ -174,11 +174,12 @@ public abstract class JdbcCacheStore<K, V> extends CacheStore<K, V> {
     protected abstract Object keyId(String type) throws CacheException;
 
     /**
-     * Prepare internal store specific builders for provided type metadata.
+     * Prepare internal store specific builders for provided types metadata.
      *
+     * @param types Collection of types.
      * @throws CacheException If failed to prepare.
      */
-    protected abstract void prepareBuilders(Collection<CacheQueryTypeMetadata> typeMetadata) throws CacheException;
+    protected abstract void prepareBuilders(Collection<CacheQueryTypeMetadata> types) throws CacheException;
 
     /**
      * Perform dialect resolution.
@@ -434,8 +435,8 @@ public abstract class JdbcCacheStore<K, V> extends CacheStore<K, V> {
                     ResultSet rs = stmt.executeQuery();
 
                     while (rs.next()) {
-                        K key = buildObject(m.keyType(), m.keyDescriptors(), rs);
-                        V val = buildObject(m.valueType(), m.valueDescriptors(), rs);
+                        K key = buildObject(m.keyType(), m.keyColumns(), rs);
+                        V val = buildObject(m.valueType(), m.valueColumns(), rs);
 
                         clo.apply(key, val);
                     }
@@ -597,7 +598,7 @@ public abstract class JdbcCacheStore<K, V> extends CacheStore<K, V> {
             ResultSet rs = stmt.executeQuery();
 
             if (rs.next())
-                return buildObject(em.valueType(), em.valueDescriptors(), rs);
+                return buildObject(em.valueType(), em.valueColumns(), rs);
         }
         catch (SQLException e) {
             throw new CacheLoaderException("Failed to load object by key: " + key, e);
@@ -924,7 +925,7 @@ public abstract class JdbcCacheStore<K, V> extends CacheStore<K, V> {
      */
     protected int fillKeyParameters(PreparedStatement stmt, int i, EntryMapping type,
         Object key) throws CacheException {
-        for (CacheQueryTypeDescriptor field : type.keyDescriptors()) {
+        for (CacheQueryTableColumnMetadata field : type.keyColumns()) {
             Object fieldVal = extractField(type.keyType(), field.getJavaName(), key);
 
             try {
@@ -960,7 +961,7 @@ public abstract class JdbcCacheStore<K, V> extends CacheStore<K, V> {
      */
     protected int fillValueParameters(PreparedStatement stmt, int i, EntryMapping m, Object val)
         throws CacheWriterException {
-        for (CacheQueryTypeDescriptor field : m.uniqValFields) {
+        for (CacheQueryTableColumnMetadata field : m.uniqValFields) {
             Object fieldVal = extractField(m.valueType(), field.getJavaName(), val);
 
             try {
@@ -1146,33 +1147,37 @@ public abstract class JdbcCacheStore<K, V> extends CacheStore<K, V> {
         private final Collection<String> cols;
 
         /** Unique value fields. */
-        private final Collection<CacheQueryTypeDescriptor> uniqValFields;
+        private final Collection<CacheQueryTableColumnMetadata> uniqValFields;
 
         /** Type metadata. */
-        private final CacheQueryTypeMetadata typeMetadata;
+        private final CacheQueryTypeMetadata typeMeta;
+
+        /** Table metadata. */
+        private final CacheQueryTableMetadata tblMeta;
 
         /**
-         * @param typeMetadata Type metadata.
+         * @param typeMeta Type metadata.
          */
-        public EntryMapping(JdbcDialect dialect, CacheQueryTypeMetadata typeMetadata) {
+        public EntryMapping(JdbcDialect dialect, CacheQueryTypeMetadata typeMeta) {
             this.dialect = dialect;
 
-            this.typeMetadata = typeMetadata;
+            this.typeMeta = typeMeta;
 
-            final Collection<CacheQueryTypeDescriptor> keyFields = typeMetadata.getKeyDescriptors();
+            tblMeta = typeMeta.getTableMetadata();
 
-            Collection<CacheQueryTypeDescriptor> valFields = typeMetadata.getValueDescriptors();
+            final Collection<CacheQueryTableColumnMetadata> keyFields = tblMeta.getKeyColumns();
 
-            uniqValFields = F.view(typeMetadata.getValueDescriptors(),
-                new IgnitePredicate<CacheQueryTypeDescriptor>() {
-                    @Override public boolean apply(CacheQueryTypeDescriptor desc) {
-                        return !keyFields.contains(desc);
-                    }
-                });
+            Collection<CacheQueryTableColumnMetadata> valFields = tblMeta.getValueColumns();
+
+            uniqValFields = F.view(valFields, new IgnitePredicate<CacheQueryTableColumnMetadata>() {
+                @Override public boolean apply(CacheQueryTableColumnMetadata col) {
+                    return !keyFields.contains(col);
+                }
+            });
 
-            String schema = typeMetadata.getSchema();
+            String schema = tblMeta.getSchema();
 
-            String tblName = typeMetadata.getTableName();
+            String tblName = tblMeta.getTableName();
 
             keyCols = databaseColumns(keyFields);
 
@@ -1202,15 +1207,15 @@ public abstract class JdbcCacheStore<K, V> extends CacheStore<K, V> {
         }
 
         /**
-         * Extract database column names from {@link CacheQueryTypeDescriptor}.
+         * Extract database column names from {@link CacheQueryTableColumnMetadata}.
          *
-         * @param dsc collection of {@link CacheQueryTypeDescriptor}.
+         * @param dsc collection of {@link CacheQueryTableColumnMetadata}.
          */
-        private static Collection<String> databaseColumns(Collection<CacheQueryTypeDescriptor> dsc) {
-            return F.transform(dsc, new C1<CacheQueryTypeDescriptor, String>() {
+        private static Collection<String> databaseColumns(Collection<CacheQueryTableColumnMetadata> dsc) {
+            return F.transform(dsc, new C1<CacheQueryTableColumnMetadata, String>() {
                 /** {@inheritDoc} */
-                @Override public String apply(CacheQueryTypeDescriptor desc) {
-                    return desc.getDbName();
+                @Override public String apply(CacheQueryTableColumnMetadata col) {
+                    return col.getDbName();
                 }
             });
         }
@@ -1229,7 +1234,7 @@ public abstract class JdbcCacheStore<K, V> extends CacheStore<K, V> {
             if (keyCnt == 1)
                 return loadQrySingle;
 
-            return dialect.loadQuery(typeMetadata.getSchema(), typeMetadata.getTableName(), keyCols, cols, keyCnt);
+            return dialect.loadQuery(tblMeta.getSchema(), tblMeta.getTableName(), keyCols, cols, keyCnt);
         }
         /**
          * Construct query for select values in range.
@@ -1239,36 +1244,36 @@ public abstract class JdbcCacheStore<K, V> extends CacheStore<K, V> {
          * @return Query with range.
          */
         protected String loadCacheRangeQuery(boolean appendLowerBound, boolean appendUpperBound) {
-            return dialect.loadCacheRangeQuery(typeMetadata.getSchema(), typeMetadata.getTableName(), keyCols, cols,
+            return dialect.loadCacheRangeQuery(tblMeta.getSchema(), tblMeta.getTableName(), keyCols, cols,
                 appendLowerBound, appendUpperBound);
         }
 
         /** Key type. */
         protected String keyType() {
-            return typeMetadata.getKeyType();
+            return typeMeta.getKeyType();
         }
 
         /** Value type. */
         protected String valueType() {
-            return typeMetadata.getType();
+            return typeMeta.getType();
         }
 
         /**
-         * Gets key fields type descriptors.
+         * Gets key columns.
          *
-         * @return Key fields type descriptors.
+         * @return Key columns.
          */
-        protected Collection<CacheQueryTypeDescriptor> keyDescriptors() {
-            return typeMetadata.getKeyDescriptors();
+        protected Collection<CacheQueryTableColumnMetadata> keyColumns() {
+            return tblMeta.getKeyColumns();
         }
 
         /**
-         * Gets value fields type descriptors.
+         * Gets value columns.
          *
-         * @return Key value type descriptors.
+         * @return Value columns.
          */
-        protected Collection<CacheQueryTypeDescriptor> valueDescriptors() {
-            return typeMetadata.getValueDescriptors();
+        protected Collection<CacheQueryTableColumnMetadata> valueColumns() {
+            return tblMeta.getValueColumns();
         }
     }
 
@@ -1313,8 +1318,8 @@ public abstract class JdbcCacheStore<K, V> extends CacheStore<K, V> {
                 ResultSet rs = stmt.executeQuery();
 
                 while (rs.next()) {
-                    K1 key = buildObject(m.keyType(), m.keyDescriptors(), rs);
-                    V1 val = buildObject(m.valueType(), m.valueDescriptors(), rs);
+                    K1 key = buildObject(m.keyType(), m.keyColumns(), rs);
+                    V1 val = buildObject(m.valueType(), m.valueColumns(), rs);
 
                     clo.apply(key, val);
                 }
@@ -1369,7 +1374,7 @@ public abstract class JdbcCacheStore<K, V> extends CacheStore<K, V> {
                 int i = 1;
 
                 for (Object key : keys)
-                    for (CacheQueryTypeDescriptor field : m.keyDescriptors()) {
+                    for (CacheQueryTableColumnMetadata field : m.keyColumns()) {
                         Object fieldVal = extractField(m.keyType(), field.getJavaName(), key);
 
                         if (fieldVal != null)
@@ -1383,8 +1388,8 @@ public abstract class JdbcCacheStore<K, V> extends CacheStore<K, V> {
                 Map<K1, V1> entries = U.newHashMap(keys.size());
 
                 while (rs.next()) {
-                    K1 key = buildObject(m.keyType(), m.keyDescriptors(), rs);
-                    V1 val = buildObject(m.valueType(), m.valueDescriptors(), rs);
+                    K1 key = buildObject(m.keyType(), m.keyColumns(), rs);
+                    V1 val = buildObject(m.valueType(), m.valueColumns(), rs);
 
                     entries.put(key, val);
                 }

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/7c1a29be/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/JdbcPojoCacheStore.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/JdbcPojoCacheStore.java b/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/JdbcPojoCacheStore.java
index 960f93f..71bb5b4 100644
--- a/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/JdbcPojoCacheStore.java
+++ b/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/JdbcPojoCacheStore.java
@@ -56,7 +56,7 @@ public class JdbcPojoCacheStore extends JdbcCacheStore<Object, Object> {
          * @param clsName Class name.
          * @param fields Fields.
          */
-        public PojoMethodsCache(String clsName, Collection<CacheQueryTypeDescriptor> fields) throws CacheException {
+        public PojoMethodsCache(String clsName, Collection<CacheQueryTableColumnMetadata> fields) throws CacheException {
 
             try {
                 cls = Class.forName(clsName);
@@ -77,7 +77,7 @@ public class JdbcPojoCacheStore extends JdbcCacheStore<Object, Object> {
 
             getters = U.newHashMap(fields.size());
 
-            for (CacheQueryTypeDescriptor field : fields) {
+            for (CacheQueryTableColumnMetadata field : fields) {
                 String prop = capitalFirst(field.getJavaName());
 
                 try {
@@ -134,29 +134,31 @@ public class JdbcPojoCacheStore extends JdbcCacheStore<Object, Object> {
     protected Map<String, PojoMethodsCache> mtdsCache;
 
     /** {@inheritDoc} */
-    @Override protected void prepareBuilders(Collection<CacheQueryTypeMetadata> typeMetadata) throws CacheException {
-        mtdsCache = U.newHashMap(typeMetadata.size() * 2);
+    @Override protected void prepareBuilders(Collection<CacheQueryTypeMetadata> types) throws CacheException {
+        mtdsCache = U.newHashMap(types.size() * 2);
 
-        for (CacheQueryTypeMetadata type : typeMetadata) {
-            PojoMethodsCache keyCache = new PojoMethodsCache(type.getKeyType(), type.getKeyDescriptors());
+        for (CacheQueryTypeMetadata type : types) {
+            CacheQueryTableMetadata tblMeta = type.getTableMetadata();
+
+            PojoMethodsCache keyCache = new PojoMethodsCache(type.getKeyType(), tblMeta.getKeyColumns());
 
             mtdsCache.put(type.getKeyType(), keyCache);
 
-            mtdsCache.put(type.getType(), new PojoMethodsCache(type.getType(), type.getValueDescriptors()));
+            mtdsCache.put(type.getType(), new PojoMethodsCache(type.getType(), tblMeta.getValueColumns()));
         }
 
         mtdsCache = Collections.unmodifiableMap(mtdsCache);
     }
 
     /** {@inheritDoc} */
-    @Override protected <R> R buildObject(String typeName, Collection<CacheQueryTypeDescriptor> fields,
+    @Override protected <R> R buildObject(String typeName, Collection<CacheQueryTableColumnMetadata> fields,
         ResultSet rs) throws CacheLoaderException {
         PojoMethodsCache t = mtdsCache.get(typeName);
 
         Object obj = t.newInstance();
 
         try {
-            for (CacheQueryTypeDescriptor field : fields)
+            for (CacheQueryTableColumnMetadata field : fields)
                 t.setters.get(field.getJavaName()).invoke(obj, rs.getObject(field.getDbName()));
 
             return (R)obj;

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/7c1a29be/modules/core/src/test/config/store/jdbc/Ignite.xml
----------------------------------------------------------------------
diff --git a/modules/core/src/test/config/store/jdbc/Ignite.xml b/modules/core/src/test/config/store/jdbc/Ignite.xml
index cc5f117..6cd8287 100644
--- a/modules/core/src/test/config/store/jdbc/Ignite.xml
+++ b/modules/core/src/test/config/store/jdbc/Ignite.xml
@@ -29,7 +29,7 @@
         <property name="tableName" value="ORGANIZATION"/>
         <property name="keyDescriptors">
             <list>
-                <bean class="org.apache.ignite.cache.query.CacheQueryTypeDescriptor">
+                <bean class="org.apache.ignite.cache.query.CacheQueryTableColumnMetadata">
                     <property name="javaName" value="id"/>
                     <property name="javaType" value="java.lang.Integer"/>
                     <property name="dbName" value="ID"/>
@@ -39,19 +39,19 @@
         </property>
         <property name="valueDescriptors">
             <list>
-                <bean class="org.apache.ignite.cache.query.CacheQueryTypeDescriptor">
+                <bean class="org.apache.ignite.cache.query.CacheQueryTableColumnMetadata">
                     <property name="javaName" value="id"/>
                     <property name="javaType" value="java.lang.Integer"/>
                     <property name="dbName" value="ID"/>
                     <property name="dbType" value="4"/>
                 </bean>
-                <bean class="org.apache.ignite.cache.query.CacheQueryTypeDescriptor">
+                <bean class="org.apache.ignite.cache.query.CacheQueryTableColumnMetadata">
                     <property name="javaName" value="name"/>
                     <property name="javaType" value="java.lang.String"/>
                     <property name="dbName" value="NAME"/>
                     <property name="dbType" value="12"/>
                 </bean>
-                <bean class="org.apache.ignite.cache.query.CacheQueryTypeDescriptor">
+                <bean class="org.apache.ignite.cache.query.CacheQueryTableColumnMetadata">
                     <property name="javaName" value="city"/>
                     <property name="javaType" value="java.lang.String"/>
                     <property name="dbName" value="CITY"/>
@@ -121,7 +121,7 @@
         <property name="tableName" value="PERSON"/>
         <property name="keyDescriptors">
             <list>
-                <bean class="org.apache.ignite.cache.query.CacheQueryTypeDescriptor">
+                <bean class="org.apache.ignite.cache.query.CacheQueryTableColumnMetadata">
                     <property name="javaName" value="id"/>
                     <property name="javaType" value="java.lang.Integer"/>
                     <property name="dbName" value="ID"/>
@@ -131,19 +131,19 @@
         </property>
         <property name="valueDescriptors">
             <list>
-                <bean class="org.apache.ignite.cache.query.CacheQueryTypeDescriptor">
+                <bean class="org.apache.ignite.cache.query.CacheQueryTableColumnMetadata">
                     <property name="javaName" value="id"/>
                     <property name="javaType" value="java.lang.Integer"/>
                     <property name="dbName" value="ID"/>
                     <property name="dbType" value="4"/>
                 </bean>
-                <bean class="org.apache.ignite.cache.query.CacheQueryTypeDescriptor">
+                <bean class="org.apache.ignite.cache.query.CacheQueryTableColumnMetadata">
                     <property name="javaName" value="orgId"/>
                     <property name="javaType" value="java.lang.Integer"/>
                     <property name="dbName" value="ORG_ID"/>
                     <property name="dbType" value="4"/>
                 </bean>
-                <bean class="org.apache.ignite.cache.query.CacheQueryTypeDescriptor">
+                <bean class="org.apache.ignite.cache.query.CacheQueryTableColumnMetadata">
                     <property name="javaName" value="name"/>
                     <property name="javaType" value="java.lang.String"/>
                     <property name="dbName" value="NAME"/>

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/7c1a29be/modules/schema-load/pom.xml
----------------------------------------------------------------------
diff --git a/modules/schema-load/pom.xml b/modules/schema-load/pom.xml
index 06cd2b3..8c5087c 100644
--- a/modules/schema-load/pom.xml
+++ b/modules/schema-load/pom.xml
@@ -40,6 +40,7 @@
             <groupId>org.apache.ignite</groupId>
             <artifactId>ignite-core</artifactId>
             <version>${ignite.version}</version>
+            <scope>test</scope>
         </dependency>
 
         <dependency>

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/7c1a29be/modules/schema-load/src/main/java/org/apache/ignite/schema/generator/XmlGenerator.java
----------------------------------------------------------------------
diff --git a/modules/schema-load/src/main/java/org/apache/ignite/schema/generator/XmlGenerator.java b/modules/schema-load/src/main/java/org/apache/ignite/schema/generator/XmlGenerator.java
index c372ad2..b56ed51 100644
--- a/modules/schema-load/src/main/java/org/apache/ignite/schema/generator/XmlGenerator.java
+++ b/modules/schema-load/src/main/java/org/apache/ignite/schema/generator/XmlGenerator.java
@@ -17,9 +17,8 @@
 
 package org.apache.ignite.schema.generator;
 
-import org.apache.ignite.cache.query.*;
-import org.apache.ignite.internal.util.typedef.*;
-import org.apache.ignite.lang.*;
+import org.apache.ignite.schema.model.*;
+import org.apache.ignite.schema.parser.*;
 import org.apache.ignite.schema.ui.*;
 import org.w3c.dom.*;
 
@@ -58,8 +57,8 @@ public class XmlGenerator {
             "    See the License for the specific language governing permissions and\n" +
             "    limitations under the License.\n"));
 
-        doc.appendChild(doc.createComment("\n    XML generated by Apache Ignite Schema Load utility: "
-            + new SimpleDateFormat("MM/DD/YYYY").format(new Date()) + "\n"));
+        doc.appendChild(doc.createComment("\n    XML generated by Apache Ignite Schema Load utility: " +
+            new SimpleDateFormat("MM/DD/YYYY").format(new Date()) + "\n"));
     }
 
     /**
@@ -69,10 +68,10 @@ public class XmlGenerator {
      * @param parent Parent XML node.
      * @param clazz Bean class.
      */
-    private static Element addBean(Document doc, Node parent, Class<?> clazz) {
+    private static Element addBean(Document doc, Node parent, String clazz) {
         Element elem = doc.createElement("bean");
 
-        elem.setAttribute("class", clazz.getName());
+        elem.setAttribute("class", clazz);
 
         parent.appendChild(elem);
 
@@ -149,14 +148,14 @@ public class XmlGenerator {
      * @param name Property name.
      * @param fields Map with fields.
      */
-    private static void addFields(Document doc, Node parent, String name, Map<String, Class<?>> fields) {
+    private static void addFields(Document doc, Node parent, String name, Collection<PojoField> fields) {
         if (!fields.isEmpty()) {
             Element prop = addProperty(doc, parent, name, null);
 
             Element map = addElement(doc, prop, "map");
 
-            for (Map.Entry<String, Class<?>> item : fields.entrySet())
-                addElement(doc, map, "entry", "key", item.getKey(), "value", item.getValue().getName());
+            for (PojoField field : fields)
+                addElement(doc, map, "entry", "key", field.javaName(), "value", field.javaTypeName());
         }
     }
 
@@ -166,42 +165,42 @@ public class XmlGenerator {
      * @param doc XML document.
      * @param parent Parent XML node.
      * @param name Property name.
-     * @param descs Map with type descriptors.
+     * @param fields Collection of POJO fields.
      */
-    private static void addTypeDescriptors(Document doc, Node parent, String name,
-        Collection<CacheQueryTypeDescriptor> descs) {
-        if (!descs.isEmpty()) {
+    private static void addTableCoumns(Document doc, Node parent, String name, Collection<PojoField> fields) {
+        if (!fields.isEmpty()) {
             Element prop = addProperty(doc, parent, name, null);
 
             Element list = addElement(doc, prop, "list");
 
-            for (CacheQueryTypeDescriptor desc : descs) {
-                Element item = addBean(doc, list, CacheQueryTypeDescriptor.class);
+            for (PojoField field : fields) {
+                Element item = addBean(doc, list, "org.apache.ignite.cache.query.CacheQueryTableColumnMetadata");
 
-                addProperty(doc, item, "javaName", desc.getJavaName());
-                addProperty(doc, item, "javaType", desc.getJavaType().getName());
-                addProperty(doc, item, "dbName", desc.getDbName());
-                addProperty(doc, item, "dbType", String.valueOf(desc.getDbType()));
+                addProperty(doc, item, "dbName", field.dbName());
+                addProperty(doc, item, "dbType", String.valueOf(field.dbType()));
+                addProperty(doc, item, "javaName", field.javaName());
+                addProperty(doc, item, "javaType", field.javaTypeName());
             }
         }
     }
 
     /**
-     * Add text fields to xml document.
+     * Add table metadata to xml document.
      *
      * @param doc XML document.
      * @param parent Parent XML node.
-     * @param textFields Collection with text fields.
+     * @param pojo POJO descriptor.
      */
-    private static void addTextFields(Document doc, Node parent, Collection<String> textFields) {
-        if (!textFields.isEmpty()) {
-            Element prop = addProperty(doc, parent, "textFields", null);
+    private static void addTableMetadata(Document doc, Node parent, PojoDescriptor pojo, boolean includeKeys) {
+        Element bean = addBean(doc, parent, "org.apache.ignite.cache.query.CacheQueryTableMetadata");
 
-            Element list = addElement(doc, prop, "list");
+        addProperty(doc, bean, "schema", pojo.schema());
 
-            for (String textField : textFields)
-                addElement(doc, list, "value").setNodeValue(textField);
-        }
+        addProperty(doc, bean, "table", pojo.table());
+
+        addTableCoumns(doc, bean, "keyColumns", pojo.keyFields());
+
+        addTableCoumns(doc, bean, "valueColumns", pojo.valueFields(includeKeys));
     }
 
     /**
@@ -211,33 +210,28 @@ public class XmlGenerator {
      * @param parent Parent XML node.
      * @param groups Map with indexes.
      */
-    private static void addGroups(Document doc, Node parent,
-        Map<String, LinkedHashMap<String, IgniteBiTuple<Class<?>, Boolean>>> groups) {
-        if (!F.isEmpty(groups)) {
+    private static void addGroups(Document doc, Node parent, Map<String, LinkedHashMap<String, DbIndex>> groups) {
+        if (!groups.isEmpty()) {
             Element prop = addProperty(doc, parent, "groups", null);
 
             Element map = addElement(doc, prop, "map");
 
-            for (Map.Entry<String, LinkedHashMap<String, IgniteBiTuple<Class<?>, Boolean>>> group : groups.entrySet()) {
+            for (Map.Entry<String, LinkedHashMap<String, DbIndex>> group : groups.entrySet()) {
                 Element entry1 = addElement(doc, map, "entry", "key", group.getKey());
 
                 Element val1 = addElement(doc, entry1, "map");
 
-                LinkedHashMap<String, IgniteBiTuple<Class<?>, Boolean>> fields = group.getValue();
+                LinkedHashMap<String, DbIndex> fields = group.getValue();
 
-                for (Map.Entry<String, IgniteBiTuple<Class<?>, Boolean>> field : fields.entrySet()) {
+                for (Map.Entry<String, DbIndex> field : fields.entrySet()) {
                     Element entry2 = addElement(doc, val1, "entry", "key", field.getKey());
 
-                    Element val2 = addBean(doc, entry2, IgniteBiTuple.class);
-
-                    IgniteBiTuple<Class<?>, Boolean> tuple = field.getValue();
+                    Element val2 = addBean(doc, entry2, "org.apache.ignite.lang.IgniteBiTuple");
 
-                    Class<?> clazz = tuple.get1();
+                    DbIndex idx = field.getValue();
 
-                    assert clazz != null;
-
-                    addElement(doc, val2, "constructor-arg", null, null, "value", clazz.getName());
-                    addElement(doc, val2, "constructor-arg", null, null, "value", String.valueOf(tuple.get2()));
+                    addElement(doc, val2, "constructor-arg", null, null, "value", idx.name());
+                    addElement(doc, val2, "constructor-arg", null, null, "value", String.valueOf(idx.descending()));
                 }
             }
         }
@@ -249,55 +243,47 @@ public class XmlGenerator {
      * @param doc XML document.
      * @param parent Parent XML node.
      * @param pkg Package fo types.
-     * @param meta Meta.
+     * @param pojo POJO descriptor.
      */
-    private static void addTypeMetadata(Document doc, Node parent, String pkg, CacheQueryTypeMetadata meta) {
-        Element bean = addBean(doc, parent, CacheQueryTypeMetadata.class);
-
-        addProperty(doc, bean, "type", pkg + "." + meta.getType());
-
-        addProperty(doc, bean, "keyType", pkg + "." + meta.getKeyType());
-
-        addProperty(doc, bean, "schema", meta.getSchema());
-
-        addProperty(doc, bean, "tableName", meta.getTableName());
+    private static void addTypeMetadata(Document doc, Node parent, String pkg, PojoDescriptor pojo, boolean includeKeys) {
+        Element bean = addBean(doc, parent, "org.apache.ignite.cache.query.CacheQueryTypeMetadata");
 
-        addTypeDescriptors(doc, bean, "keyDescriptors", meta.getKeyDescriptors());
+        addProperty(doc, bean, "type", pkg + "." + pojo.valueClassName());
 
-        addTypeDescriptors(doc, bean, "valueDescriptors", meta.getValueDescriptors());
+        addProperty(doc, bean, "keyType", pkg + "." + pojo.keyClassName());
 
-        addFields(doc, bean, "queryFields", meta.getQueryFields());
+        addTableMetadata(doc, bean, pojo, includeKeys);
 
-        addFields(doc, bean, "ascendingFields", meta.getAscendingFields());
+        addFields(doc, bean, "queryFields", pojo.fields());
 
-        addFields(doc, bean, "descendingFields", meta.getDescendingFields());
+        addFields(doc, bean, "ascendingFields", pojo.ascendingFields());
 
-        addTextFields(doc, bean, meta.getTextFields());
+        addFields(doc, bean, "descendingFields", pojo.descendingFields());
 
-        addGroups(doc, bean, meta.getGroups());
+//        addGroups(doc, bean, typeMeta.getGroups());
     }
 
     /**
      * Transform metadata into xml.
      *
      * @param pkg Package fo types.
-     * @param meta Metadata to generate.
+     * @param pojo POJO descriptor.
      * @param out File to output result.
      * @param askOverwrite Callback to ask user to confirm file overwrite.
      */
-    public static void generate(String pkg, CacheQueryTypeMetadata meta, File out, ConfirmCallable askOverwrite) {
-        generate(pkg, Collections.singleton(meta), out, askOverwrite);
+    public static void generate(String pkg, PojoDescriptor pojo, boolean includeKeys, File out, ConfirmCallable askOverwrite) {
+        generate(pkg, Collections.singleton(pojo), includeKeys, out, askOverwrite);
     }
 
     /**
      * Transform metadata into xml.
      *
      * @param pkg Package fo types.
-     * @param meta Metadata to generate.
+     * @param pojos POJO descriptors.
      * @param out File to output result.
      * @param askOverwrite Callback to ask user to confirm file overwrite.
      */
-    public static void generate(String pkg, Collection<CacheQueryTypeMetadata> meta, File out,
+    public static void generate(String pkg, Collection<PojoDescriptor> pojos, boolean includeKeys, File out,
         ConfirmCallable askOverwrite) {
 
         File outFolder = out.getParentFile();
@@ -335,8 +321,8 @@ public class XmlGenerator {
                 "http://www.springframework.org/schema/beans " +
                 "http://www.springframework.org/schema/beans/spring-beans.xsd");
 
-            for (CacheQueryTypeMetadata item : meta)
-                addTypeMetadata(doc, beans, pkg, item);
+            for (PojoDescriptor pojo : pojos)
+                addTypeMetadata(doc, beans, pkg, pojo, includeKeys);
 
             TransformerFactory transformerFactory = TransformerFactory.newInstance();
 

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/7c1a29be/modules/schema-load/src/main/java/org/apache/ignite/schema/model/PojoDescriptor.java
----------------------------------------------------------------------
diff --git a/modules/schema-load/src/main/java/org/apache/ignite/schema/model/PojoDescriptor.java b/modules/schema-load/src/main/java/org/apache/ignite/schema/model/PojoDescriptor.java
index 59e601a..be69cc6 100644
--- a/modules/schema-load/src/main/java/org/apache/ignite/schema/model/PojoDescriptor.java
+++ b/modules/schema-load/src/main/java/org/apache/ignite/schema/model/PojoDescriptor.java
@@ -20,40 +20,43 @@ package org.apache.ignite.schema.model;
 import javafx.beans.property.*;
 import javafx.beans.value.*;
 import javafx.collections.*;
-import org.apache.ignite.cache.query.*;
+import org.apache.ignite.schema.parser.*;
 
+import java.math.*;
 import java.util.*;
 
+import static java.sql.Types.*;
+
 /**
  * Descriptor for java type.
  */
 public class PojoDescriptor {
-    /** Selected property. */
-    private final BooleanProperty use;
+    /** Database table. */
+    private final DbTable tbl;
 
-    /** Key class name to show on screen. */
-    private final StringProperty keyClsName;
+    /** Selected property. */
+    private final BooleanProperty useProp;
 
     /** Previous name for key class. */
     private final String keyClsNamePrev;
 
-    /** Value class name to show on screen. */
-    private final StringProperty valClsName;
+    /** Key class name to show on screen. */
+    private final StringProperty keyClsNameProp;
 
     /** Previous name for value class. */
     private final String valClsNamePrev;
 
+    /** Value class name to show on screen. */
+    private final StringProperty valClsNameProp;
+
     /** Parent item (schema name). */
     private final PojoDescriptor parent;
 
-    /** Type metadata. */
-    private final CacheQueryTypeMetadata typeMeta;
-
     /** Children items (tables names). */
     private Collection<PojoDescriptor> children = Collections.emptyList();
 
     /** Indeterminate state of parent. */
-    private final BooleanProperty indeterminate = new SimpleBooleanProperty(false);
+    private final BooleanProperty indeterminateProp = new SimpleBooleanProperty(false);
 
     /** Full database name: schema + table. */
     private final String fullDbName;
@@ -62,75 +65,68 @@ public class PojoDescriptor {
     private final ObservableList<PojoField> fields;
 
     /**
-     * Create special descriptor for database schema.
-     *
-     * @param schema Database schema name.
-     * @return New {@code PojoDescriptor} instance.
-     */
-    public static PojoDescriptor schema(String schema) {
-        CacheQueryTypeMetadata typeMeta = new CacheQueryTypeMetadata();
-
-        typeMeta.setSchema(schema);
-        typeMeta.setTableName("");
-        typeMeta.setKeyType("");
-        typeMeta.setType("");
-
-        return new PojoDescriptor(null, typeMeta, Collections.<PojoField>emptyList());
-    }
-
-    /**
      * Constructor of POJO descriptor.
      *
      * @param prn Parent descriptor.
-     * @param typeMeta Type metadata descriptor.
-     * @param fields List of POJO fields.
+     * @param tbl Database table Tab;e.
      */
-    public PojoDescriptor(PojoDescriptor prn, CacheQueryTypeMetadata typeMeta, List<PojoField> fields) {
+    public PojoDescriptor(PojoDescriptor prn, DbTable tbl) {
         parent = prn;
 
-        fullDbName = typeMeta.getSchema() + "." + typeMeta.getTableName();
+        this.tbl = tbl;
 
-        keyClsNamePrev = typeMeta.getKeyType();
-        keyClsName = new SimpleStringProperty(keyClsNamePrev);
+        fullDbName = tbl.schema() + "." + tbl.table();
 
-        valClsNamePrev = typeMeta.getType();
-        valClsName = new SimpleStringProperty(valClsNamePrev);
+        valClsNamePrev = toJavaClassName(tbl.table());
+        valClsNameProp = new SimpleStringProperty(valClsNamePrev);
 
-        use = new SimpleBooleanProperty(true);
+        keyClsNamePrev = valClsNamePrev.isEmpty() ? "" : valClsNamePrev + "Key";
+        keyClsNameProp = new SimpleStringProperty(keyClsNamePrev);
 
-        use.addListener(new ChangeListener<Boolean>() {
+        useProp = new SimpleBooleanProperty(true);
+
+        useProp.addListener(new ChangeListener<Boolean>() {
             @Override public void changed(ObservableValue<? extends Boolean> val, Boolean oldVal, Boolean newVal) {
                 for (PojoDescriptor child : children)
-                    child.use.set(newVal);
+                    child.useProp.set(newVal);
 
                 if (parent != null && !parent.children.isEmpty()) {
                     Iterator<PojoDescriptor> it = parent.children.iterator();
 
                     boolean parentIndeterminate = false;
-                    boolean first = it.next().use.get();
+                    boolean first = it.next().useProp.get();
 
                     while (it.hasNext()) {
-                        if (it.next().use.get() != first) {
+                        if (it.next().useProp.get() != first) {
                             parentIndeterminate = true;
 
                             break;
                         }
                     }
 
-                    parent.indeterminate.set(parentIndeterminate);
+                    parent.indeterminateProp.set(parentIndeterminate);
 
                     if (!parentIndeterminate)
-                        parent.use.set(first);
+                        parent.useProp.set(first);
                 }
             }
         });
 
-        this.fields = FXCollections.observableList(fields);
+        Collection<DbColumn> cols = tbl.columns();
 
-        for (PojoField field : fields)
-            field.owner(this);
+        List<PojoField> flds = new ArrayList<>(cols.size());
+
+        for (DbColumn col : cols) {
+            PojoField fld = new PojoField(col.name(), col.type(),
+                toJavaFieldName(col.name()), toJavaType(col.type(), col.nullable()).getName(),
+                col.key(), col.nullable());
+
+            fld.owner(this);
 
-        this.typeMeta = typeMeta;
+            flds.add(fld);
+        }
+
+        fields = FXCollections.observableList(flds);
     }
 
     /**
@@ -151,49 +147,49 @@ public class PojoDescriptor {
      * @return {@code true} if POJO descriptor is a table descriptor and checked in GUI.
      */
     public boolean checked() {
-        return parent != null && use.get();
+        return parent != null && useProp.get();
     }
 
     /**
      * @return Boolean property support for {@code use} property.
      */
     public BooleanProperty useProperty() {
-        return use;
+        return useProp;
     }
 
     /**
      * @return Boolean property support for parent {@code indeterminate} property.
      */
     public BooleanProperty indeterminate() {
-        return indeterminate;
+        return indeterminateProp;
     }
 
     /**
      * @return Key class name.
      */
     public String keyClassName() {
-        return keyClsName.get();
+        return keyClsNameProp.get();
     }
 
     /**
      * @param name New key class name.
      */
     public void keyClassName(String name) {
-        keyClsName.set(name);
+        keyClsNameProp.set(name);
     }
 
     /**
      * @return Value class name.
      */
     public String valueClassName() {
-        return valClsName.get();
+        return valClsNameProp.get();
     }
 
     /**
      * @param name New value class name.
      */
     public void valueClassName(String name) {
-        valClsName.set(name);
+        valClsNameProp.set(name);
     }
 
     /**
@@ -230,28 +226,28 @@ public class PojoDescriptor {
      * @return Key class name property.
      */
     public StringProperty keyClassNameProperty() {
-        return keyClsName;
+        return keyClsNameProp;
     }
 
     /**
      * @return Value class name property.
      */
     public StringProperty valueClassNameProperty() {
-        return valClsName;
+        return valClsNameProp;
     }
 
     /**
      * @return Schema name.
      */
     public String schema() {
-        return typeMeta.getSchema();
+        return tbl.schema();
     }
 
     /**
      * @return Table name.
      */
     public String table() {
-        return typeMeta.getTableName();
+        return tbl.table();
     }
 
     /**
@@ -267,7 +263,7 @@ public class PojoDescriptor {
      * @return {@code true} if descriptor was changed by user via GUI.
      */
     public boolean changed() {
-        if (!keyClsName.get().equals(keyClsNamePrev) || !valClsName.get().equals(valClsNamePrev))
+        if (!keyClsNameProp.get().equals(keyClsNamePrev) || !valClsNameProp.get().equals(valClsNamePrev))
             return true;
 
         for (PojoField field : fields)
@@ -281,14 +277,14 @@ public class PojoDescriptor {
      * Revert changes to key class name made by user.
      */
     public void revertKeyClassName() {
-       keyClsName.set(keyClsNamePrev);
+        keyClsNameProp.set(keyClsNamePrev);
     }
 
     /**
      * Revert changes to value class name made by user.
      */
     public void revertValueClassName() {
-        valClsName.set(valClsNamePrev);
+        valClsNameProp.set(valClsNamePrev);
     }
 
     /**
@@ -300,6 +296,36 @@ public class PojoDescriptor {
     }
 
     /**
+     * @return Ascending fields.
+     */
+    public Collection<PojoField> ascendingFields() {
+        Collection<PojoField> res = new ArrayList<>();
+
+        Set<String> asc = tbl.ascendingColumns();
+
+        for (PojoField field : fields)
+            if (asc.contains(field.dbName()))
+                res.add(field);
+
+        return res;
+    }
+
+    /**
+     * @return Descending fields.
+     */
+    public Collection<PojoField> descendingFields() {
+        Collection<PojoField> res = new ArrayList<>();
+
+        Set<String> desc = tbl.descendingColumns();
+
+        for (PojoField field : fields)
+            if (desc.contains(field.dbName()))
+                res.add(field);
+
+        return res;
+    }
+
+    /**
      * @return Java class fields.
      */
     public ObservableList<PojoField> fields() {
@@ -307,32 +333,100 @@ public class PojoDescriptor {
     }
 
     /**
-     * @param includeKeys {@code true} if key fields should be included into value class.
-     * @return Type metadata updated with user changes.
+     * @param name Source name.
+     * @return String converted to java class name notation.
      */
-    public CacheQueryTypeMetadata metadata(boolean includeKeys) {
-        typeMeta.setKeyType(keyClsName.get());
-        typeMeta.setType(valClsName.get());
+    private static String toJavaClassName(String name) {
+        int len = name.length();
 
-        Collection<CacheQueryTypeDescriptor> keys = new ArrayList<>();
+        StringBuilder buf = new StringBuilder(len);
 
-        Collection<CacheQueryTypeDescriptor> vals = new ArrayList<>();
+        boolean capitalizeNext = true;
 
-        for (PojoField field : fields) {
-            if (field.key()) {
-                keys.add(field.descriptor());
+        for (int i = 0; i < len; i++) {
+            char ch = name.charAt(i);
 
-                if (includeKeys)
-                    vals.add(field.descriptor());
+            if (Character.isWhitespace(ch) || '_' == ch)
+                capitalizeNext = true;
+            else if (capitalizeNext) {
+                buf.append(Character.toUpperCase(ch));
+
+                capitalizeNext = false;
             }
             else
-                vals.add(field.descriptor());
+                buf.append(Character.toLowerCase(ch));
         }
 
-        typeMeta.setKeyDescriptors(keys);
+        return buf.toString();
+    }
+
+    /**
+     * @param name Source name.
+     * @return String converted to java field name notation.
+     */
+    private static String toJavaFieldName(String name) {
+        String javaName = toJavaClassName(name);
+
+        return Character.toLowerCase(javaName.charAt(0)) + javaName.substring(1);
+    }
+
+    /**
+     * Convert JDBC data type to java type.
+     *
+     * @param type JDBC SQL data type.
+     * @param nullable {@code true} if {@code NULL} is allowed for this field in database.
+     * @return Java data type.
+     */
+    private static Class<?> toJavaType(int type, boolean nullable) {
+        switch (type) {
+            case BIT:
+            case BOOLEAN:
+                return nullable ? Boolean.class : boolean.class;
+
+            case TINYINT:
+                return nullable ? Byte.class : byte.class;
+
+            case SMALLINT:
+                return nullable ? Short.class : short.class;
+
+            case INTEGER:
+                return nullable ? Integer.class : int.class;
+
+            case BIGINT:
+                return nullable ? Long.class : long.class;
 
-        typeMeta.setValueDescriptors(vals);
+            case REAL:
+                return nullable ? Float.class : float.class;
 
-        return typeMeta;
+            case FLOAT:
+            case DOUBLE:
+                return nullable ? Double.class : double.class;
+
+            case NUMERIC:
+            case DECIMAL:
+                return BigDecimal.class;
+
+            case CHAR:
+            case VARCHAR:
+            case LONGVARCHAR:
+            case NCHAR:
+            case NVARCHAR:
+            case LONGNVARCHAR:
+                return String.class;
+
+            case DATE:
+                return java.sql.Date.class;
+
+            case TIME:
+                return java.sql.Time.class;
+
+            case TIMESTAMP:
+                return java.sql.Timestamp.class;
+
+            // BINARY, VARBINARY, LONGVARBINARY, ARRAY, BLOB, CLOB, NCLOB, NULL, DATALINK
+            // OTHER, JAVA_OBJECT, DISTINCT, STRUCT, REF, ROWID, SQLXML
+            default:
+                return Object.class;
+        }
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/7c1a29be/modules/schema-load/src/main/java/org/apache/ignite/schema/model/PojoField.java
----------------------------------------------------------------------
diff --git a/modules/schema-load/src/main/java/org/apache/ignite/schema/model/PojoField.java b/modules/schema-load/src/main/java/org/apache/ignite/schema/model/PojoField.java
index c7e8b07..507d5db 100644
--- a/modules/schema-load/src/main/java/org/apache/ignite/schema/model/PojoField.java
+++ b/modules/schema-load/src/main/java/org/apache/ignite/schema/model/PojoField.java
@@ -20,7 +20,6 @@ package org.apache.ignite.schema.model;
 import javafx.beans.property.*;
 import javafx.beans.value.*;
 import javafx.collections.*;
-import org.apache.ignite.cache.query.*;
 
 import java.math.*;
 import java.util.*;
@@ -32,47 +31,44 @@ import static java.sql.Types.*;
  */
 public class PojoField {
     /** If this field should be used for code generation. */
-    private final BooleanProperty use;
+    private final BooleanProperty useProp;
 
     /** If this field belongs to primary key. */
-    private final BooleanProperty key;
+    private final BooleanProperty keyProp;
 
     /** If this field is an affinity key. */
-    private final BooleanProperty ak;
+    private final BooleanProperty akProp;
 
     /** If this field initially belongs to primary key. */
     private final boolean keyPrev;
 
-    /** Field name for POJO. */
-    private final StringProperty javaName;
-
-    /** Initial field name for POJO. */
-    private final String javaNamePrev;
-
-    /** Field type for POJO. */
-    private final StringProperty javaTypeName;
-
-    /** Initial field type for POJO. */
-    private final String javaTypeNamePrev;
-
     /** Field name in database. */
-    private final StringProperty dbName;
+    private final StringProperty dbNameProp;
 
     /** JDBC field type in database. */
     private final int dbType;
 
     /** Field type in database. */
-    private final StringProperty dbTypeName;
+    private final StringProperty dbTypeNameProp;
+
+    /** Field name in POJO. */
+    private final StringProperty javaNameProp;
+
+    /** Initial field name in POJO. */
+    private final String javaNamePrev;
+
+    /** Field type in POJO. */
+    private final StringProperty javaTypeNameProp;
+
+    /** Initial field type in POJO. */
+    private final String javaTypeNamePrev;
 
-    /** Is NULL allowed for field in database. */
+    /** Is {@code NULL} allowed for field in database. */
     private final boolean nullable;
 
     /** List of possible java type conversions. */
     private final ObservableList<String> conversions;
 
-    /** Field type descriptor. */
-    private final CacheQueryTypeDescriptor desc;
-
     /** Field owner. */
     private PojoDescriptor owner;
 
@@ -99,34 +95,15 @@ public class PojoField {
     private static final List<String> PRIMITIVES = classNames(boolean.class, byte.class, short.class,
         int.class, long.class, float.class, double.class);
 
-    /** Java types. */
-    private static final Class<?>[] JAVA_TYPES = new Class<?>[] {
-        boolean.class, Boolean.class,
-        byte.class, Byte.class,
-        short.class, Short.class,
-        int.class, Integer.class,
-        long.class, Long.class,
-        float.class, Float.class,
-        double.class, Double.class,
-        BigDecimal.class,
-        String.class,
-        java.sql.Date.class, java.sql.Time.class, java.sql.Timestamp.class,
-        Object.class};
-
-    /** */
-    private static final Map<String, Class<?>> classesMap = new HashMap<>();
+    /** Object types. */
+    private static final List<String> OBJECTS = classNames(Boolean.class, Byte.class, Short.class, Integer.class,
+        Long.class, Float.class, Double.class, BigDecimal.class);
 
     static {
-        List<String> objects = classNames(Boolean.class, Byte.class, Short.class, Integer.class,
-            Long.class, Float.class, Double.class, BigDecimal.class);
-
         NOT_NULL_NUM_CONVERSIONS.addAll(PRIMITIVES);
-        NOT_NULL_NUM_CONVERSIONS.addAll(objects);
+        NOT_NULL_NUM_CONVERSIONS.addAll(OBJECTS);
 
-        NULL_NUM_CONVERSIONS.addAll(objects);
-
-        for (Class<?> cls : JAVA_TYPES)
-            classesMap.put(cls.getName(), cls);
+        NULL_NUM_CONVERSIONS.addAll(OBJECTS);
     }
 
     /**
@@ -152,54 +129,55 @@ public class PojoField {
     }
 
     /**
-     * @param isKey {@code true} if this field belongs to primary key.
-     * @param desc Field type descriptor.
-     * @param nullable {@code true} if {@code NULL} is allowed for this field in database.
+     * @param dbName Field name in database.
+     * @param dbType Field JDBC type in database.
+     * @param javaName Field name in POJO.
+     * @param javaTypeName Field type in POJO.
+     * @param key {@code true} if this field belongs to primary key.
+     * @param nullable {@code true} if  {@code NULL} allowed for field in database.
      */
-    public PojoField(boolean isKey, CacheQueryTypeDescriptor desc, boolean nullable) {
-        keyPrev = isKey;
+    public PojoField(String dbName, int dbType, String javaName, String javaTypeName, boolean key, boolean nullable) {
+        dbNameProp = new SimpleStringProperty(dbName);
 
-        use = new SimpleBooleanProperty(true);
+        this.dbType = dbType;
 
-        key = new SimpleBooleanProperty(keyPrev);
+        dbTypeNameProp = new SimpleStringProperty(jdbcTypeName(dbType));
 
-        ak = new SimpleBooleanProperty(false);
+        javaNamePrev = javaName;
 
-        javaNamePrev = desc.getJavaName();
+        javaNameProp = new SimpleStringProperty(javaNamePrev);
 
-        javaName = new SimpleStringProperty(javaNamePrev);
+        javaTypeNamePrev = javaTypeName;
 
-        javaTypeNamePrev = desc.getJavaType().getName();
+        javaTypeNameProp = new SimpleStringProperty(javaTypeNamePrev);
 
-        javaTypeName = new SimpleStringProperty(javaTypeNamePrev);
+        keyPrev = key;
 
-        dbName = new SimpleStringProperty(desc.getDbName());
+        keyProp = new SimpleBooleanProperty(keyPrev);
 
-        dbType = desc.getDbType();
+        this.nullable = nullable;
 
-        dbTypeName = new SimpleStringProperty(jdbcTypeName(dbType));
+        useProp = new SimpleBooleanProperty(true);
 
-        this.nullable = nullable;
+        akProp = new SimpleBooleanProperty(false);
 
         conversions = conversions(dbType, nullable, javaNamePrev);
 
-        this.desc = desc;
-
-        key.addListener(new ChangeListener<Boolean>() {
+        keyProp.addListener(new ChangeListener<Boolean>() {
             @Override public void changed(ObservableValue<? extends Boolean> val, Boolean oldVal, Boolean newVal) {
                 if (!newVal)
-                    ak.set(false);
+                    akProp.set(false);
             }
         });
 
-        ak.addListener(new ChangeListener<Boolean>() {
+        akProp.addListener(new ChangeListener<Boolean>() {
             @Override public void changed(ObservableValue<? extends Boolean> val, Boolean oldVal, Boolean newVal) {
                 if (newVal && owner != null) {
                     keyProperty().set(true);
 
                     for (PojoField field : owner.fields())
                         if (field != PojoField.this && field.affinityKey())
-                            field.ak.set(false);
+                            field.akProp.set(false);
                 }
             }
         });
@@ -291,7 +269,7 @@ public class PojoField {
      * Revert changes to java names made by user.
      */
     public void resetJavaName() {
-        javaName.setValue(javaNamePrev);
+        javaNameProp.set(javaNamePrev);
     }
 
     /**
@@ -305,49 +283,49 @@ public class PojoField {
      * @return {@code true} if this field belongs to primary key.
      */
     public boolean key() {
-        return key.get();
+        return keyProp.get();
     }
 
     /**
-     * @return {@code true} if this field is an affinity key.
+     * @param pk {@code true} if this field belongs to primary key.
      */
-    public boolean affinityKey() {
-        return ak.get();
+    public void key(boolean pk) {
+        keyProp.set(pk);
     }
 
     /**
-     * @param pk {@code true} if this field belongs to primary key.
+     * @return {@code true} if this field is an affinity key.
      */
-    public void key(boolean pk) {
-        key.set(pk);
+    public boolean affinityKey() {
+        return akProp.get();
     }
 
     /**
      * @return POJO field java name.
      */
     public String javaName() {
-        return javaName.get();
+        return javaNameProp.get();
     }
 
     /**
      * @param name New POJO field java name.
      */
     public void javaName(String name) {
-        javaName.set(name);
+        javaNameProp.set(name);
     }
 
     /**
      * @return POJO field java type name.
      */
     public String javaTypeName() {
-        return javaTypeName.get();
+        return javaTypeNameProp.get();
     }
 
     /**
      * @return Field name in database.
      */
     public String dbName() {
-        return dbName.get();
+        return dbNameProp.get();
     }
 
     /**
@@ -372,16 +350,6 @@ public class PojoField {
     }
 
     /**
-     * @return Field type descriptor.
-     */
-    public CacheQueryTypeDescriptor descriptor() {
-        desc.setJavaName(javaName());
-        desc.setJavaType(classesMap.get(javaTypeName()));
-
-        return desc;
-    }
-
-    /**
      * @return {@code true} if type of field is primitive type.
      */
     public boolean primitive() {
@@ -399,48 +367,48 @@ public class PojoField {
      * @return Boolean property support for {@code use} property.
      */
     public BooleanProperty useProperty() {
-        return use;
+        return useProp;
     }
 
     /**
      * @return Boolean property support for {@code key} property.
      */
     public BooleanProperty keyProperty() {
-        return key;
+        return keyProp;
     }
 
     /**
      * @return Boolean property support for {@code affinityKey} property.
      */
     public BooleanProperty affinityKeyProperty() {
-        return ak;
+        return akProp;
     }
 
     /**
      * @return String property support for {@code javaName} property.
      */
     public StringProperty javaNameProperty() {
-        return javaName;
+        return javaNameProp;
     }
 
     /**
      * @return String property support for {@code javaTypeName} property.
      */
     public StringProperty javaTypeNameProperty() {
-        return javaTypeName;
+        return javaTypeNameProp;
     }
 
     /**
      * @return String property support for {@code dbName} property.
      */
     public StringProperty dbNameProperty() {
-        return dbName;
+        return dbNameProp;
     }
 
     /**
      * @return String property support for {@code dbName} property.
      */
     public StringProperty dbTypeNameProperty() {
-        return dbTypeName;
+        return dbTypeNameProp;
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/7c1a29be/modules/schema-load/src/main/java/org/apache/ignite/schema/parser/DatabaseMetadataParser.java
----------------------------------------------------------------------
diff --git a/modules/schema-load/src/main/java/org/apache/ignite/schema/parser/DatabaseMetadataParser.java b/modules/schema-load/src/main/java/org/apache/ignite/schema/parser/DatabaseMetadataParser.java
index 309f127..4f57b07 100644
--- a/modules/schema-load/src/main/java/org/apache/ignite/schema/parser/DatabaseMetadataParser.java
+++ b/modules/schema-load/src/main/java/org/apache/ignite/schema/parser/DatabaseMetadataParser.java
@@ -18,265 +18,120 @@
 package org.apache.ignite.schema.parser;
 
 import javafx.collections.*;
-import org.apache.ignite.cache.query.*;
-import org.apache.ignite.lang.*;
 import org.apache.ignite.schema.model.*;
+import org.apache.ignite.schema.parser.dialect.*;
 
-import java.math.*;
 import java.sql.*;
 import java.util.*;
 
-import static java.sql.Types.*;
-
 /**
  * Database metadata parser.
  */
 public class DatabaseMetadataParser {
-    /**
-     * @param name Source name.
-     * @return String converted to java class name notation.
-     */
-    private static String toJavaClassName(String name) {
-        int len = name.length();
-
-        StringBuilder buf = new StringBuilder(len);
-
-        boolean capitalizeNext = true;
-
-        for (int i = 0; i < len; i++) {
-            char ch = name.charAt(i);
-
-            if (Character.isWhitespace(ch) || '_' == ch)
-                capitalizeNext = true;
-            else if (capitalizeNext) {
-                buf.append(Character.toUpperCase(ch));
-
-                capitalizeNext = false;
-            }
-            else
-                buf.append(Character.toLowerCase(ch));
-        }
-
-        return buf.toString();
-    }
-
-    /**
-     * @param name Source name.
-     * @return String converted to java field name notation.
-     */
-    private static String toJavaFieldName(String name) {
-        String javaName = toJavaClassName(name);
-
-        return Character.toLowerCase(javaName.charAt(0)) + javaName.substring(1);
-    }
-
-    /**
-     * Convert JDBC data type to java type.
-     *
-     * @param type JDBC SQL data type.
-     * @param nullable {@code true} if {@code NULL} is allowed for this field in database.
-     * @return Java data type.
-     */
-    private static Class<?> dataType(int type, boolean nullable) {
-        switch (type) {
-            case BIT:
-            case BOOLEAN:
-                return nullable ? Boolean.class : boolean.class;
-
-            case TINYINT:
-                return nullable ? Byte.class : byte.class;
-
-            case SMALLINT:
-                return nullable ? Short.class : short.class;
-
-            case INTEGER:
-                return nullable ? Integer.class : int.class;
-
-            case BIGINT:
-                return nullable ? Long.class : long.class;
-
-            case REAL:
-                return nullable ? Float.class : float.class;
-
-            case FLOAT:
-            case DOUBLE:
-                return nullable ? Double.class : double.class;
-
-            case NUMERIC:
-            case DECIMAL:
-                return BigDecimal.class;
-
-            case CHAR:
-            case VARCHAR:
-            case LONGVARCHAR:
-            case NCHAR:
-            case NVARCHAR:
-            case LONGNVARCHAR:
-                return String.class;
-
-            case DATE:
-                return java.sql.Date.class;
-
-            case TIME:
-                return java.sql.Time.class;
-
-            case TIMESTAMP:
-                return java.sql.Timestamp.class;
-
-            // BINARY, VARBINARY, LONGVARBINARY, ARRAY, BLOB, CLOB, NCLOB, NULL, DATALINK
-            // OTHER, JAVA_OBJECT, DISTINCT, STRUCT, REF, ROWID, SQLXML
-            default:
-                return Object.class;
-        }
-    }
+//        try (ResultSet idxs = dbMeta.getIndexInfo(catalog, schema, tbl, false, true)) {
+//            while (idxs.next()) {
+//                String idxName = idxs.getString(6);
+//
+//                String colName = idxs.getString(9);
+//
+//                if (idxName == null || colName == null)
+//                    continue;
+//
+//                String idx = toJavaFieldName(idxName);
+//
+//                String col = toJavaFieldName(colName);
+//
+//                String askOrDesc = idxs.getString(10);
+//
+//                LinkedHashMap<String, IgniteBiTuple<Class<?>, Boolean>> idxCols = groups.get(idx);
+//
+//                if (idxCols == null) {
+//                    idxCols = new LinkedHashMap<>();
+//
+//                    groups.put(idx, idxCols);
+//                }
+//
+//                Class<?> dataType = qryFields.get(col);
+//
+//                Boolean desc = askOrDesc != null ? "D".equals(askOrDesc) : null;
+//
+//                if (desc != null) {
+//                    if (desc)
+//                        descFields.put(col, dataType);
+//                    else
+//                        ascFields.put(col, dataType);
+//                }
+//
+//                idxCols.put(col, new IgniteBiTuple<Class<?>, Boolean>(dataType, desc));
+//            }
+//        }
+//
+//        return new PojoDescriptor(parent, typeMeta, fields);
+//    }
 
     /**
      * Parse database metadata.
      *
-     * @param dbMeta Database metadata.
-     * @param catalog Catalog name.
-     * @param schema Schema name.
-     * @param tbl Table name.
-     * @return New initialized instance of {@code CacheQueryTypeMetadata}.
+     * @param conn Connection to database.
+     * @param tblsOnly If {@code true} then process tables only else process tables and views.
+     * @return Collection of POJO descriptors.
      * @throws SQLException If parsing failed.
      */
-    private static PojoDescriptor parseTable(PojoDescriptor parent, DatabaseMetaData dbMeta, String catalog,
-        String schema, String tbl) throws SQLException {
-        CacheQueryTypeMetadata typeMeta = new CacheQueryTypeMetadata();
-
-        typeMeta.setSchema(schema);
-        typeMeta.setTableName(tbl);
-
-        typeMeta.setType(toJavaClassName(tbl));
-        typeMeta.setKeyType(typeMeta.getType() + "Key");
-
-        Collection<CacheQueryTypeDescriptor> keyDescs = typeMeta.getKeyDescriptors();
-        Collection<CacheQueryTypeDescriptor> valDescs = typeMeta.getValueDescriptors();
-
-        Map<String, Class<?>> qryFields = typeMeta.getQueryFields();
-        Map<String, Class<?>> ascFields = typeMeta.getAscendingFields();
-        Map<String, Class<?>> descFields = typeMeta.getDescendingFields();
-        Map<String, LinkedHashMap<String, IgniteBiTuple<Class<?>, Boolean>>> groups = typeMeta.getGroups();
+    public static ObservableList<PojoDescriptor> parse(Connection conn, boolean tblsOnly) throws SQLException {
+        DatabaseMetadataDialect dialect;
 
-        Set<String> pkFlds = new LinkedHashSet<>();
+        try {
+            String dbProductName = conn.getMetaData().getDatabaseProductName();
 
-        try (ResultSet pk = dbMeta.getPrimaryKeys(catalog, schema, tbl)) {
-            while (pk.next())
-                pkFlds.add(pk.getString(4));
+            if ("Oracle".equals(dbProductName))
+                dialect = new OracleMetadataDialect();
+            else if (dbProductName.startsWith("DB2/"))
+                dialect = new DB2MetadataDialect();
+            else
+                dialect = new JdbcMetadataDialect();
         }
+        catch (SQLException e) {
+            System.err.println("Failed to resolve dialect (JdbcMetaDataDialect will be used.");
+            e.printStackTrace();
 
-        List<PojoField> fields = new ArrayList<>();
-
-        try (ResultSet cols = dbMeta.getColumns(catalog, schema, tbl, null)) {
-            while (cols.next()) {
-                String dbName = cols.getString(4);
-
-                int dbType = cols.getInt(5);
-
-                boolean nullable = cols.getInt(11) == DatabaseMetaData.columnNullable;
-
-                String javaName = toJavaFieldName(dbName);
-
-                Class<?> javaType = dataType(dbType, nullable);
-
-                CacheQueryTypeDescriptor desc = new CacheQueryTypeDescriptor(javaName, javaType, dbName, dbType);
-
-                boolean key = pkFlds.contains(dbName);
-
-                if (key)
-                    keyDescs.add(desc);
-                else
-                    valDescs.add(desc);
-
-                qryFields.put(javaName, javaType);
-
-                fields.add(new PojoField(key, desc, nullable));
-            }
+            dialect = new JdbcMetadataDialect();
         }
 
-        try (ResultSet idxs = dbMeta.getIndexInfo(catalog, schema, tbl, false, true)) {
-            while (idxs.next()) {
-                String idxName = idxs.getString(6);
-
-                String colName = idxs.getString(9);
-
-                if (idxName == null || colName == null)
-                    continue;
-
-                String idx = toJavaFieldName(idxName);
-
-                String col = toJavaFieldName(colName);
-
-                String askOrDesc = idxs.getString(10);
+        Map<String, PojoDescriptor> parents = new HashMap<>();
 
-                LinkedHashMap<String, IgniteBiTuple<Class<?>, Boolean>> idxCols = groups.get(idx);
+        Map<String, Collection<PojoDescriptor>> childrens = new HashMap<>();
 
-                if (idxCols == null) {
-                    idxCols = new LinkedHashMap<>();
+        for (DbTable tbl : dialect.tables(conn, tblsOnly)) {
+            String schema = tbl.schema();
 
-                    groups.put(idx, idxCols);
-                }
+            PojoDescriptor parent = parents.get(schema);
+            Collection<PojoDescriptor> children = childrens.get(schema);
 
-                Class<?> dataType = qryFields.get(col);
+            if (parent == null) {
+                parent = new PojoDescriptor(null, new DbTable(schema, "", Collections.<DbColumn>emptyList(),
+                    Collections.<String>emptySet(), Collections.<String>emptySet(),
+                    Collections.<String, Map<String, Boolean>>emptyMap()));
 
-                Boolean desc = askOrDesc != null ? "D".equals(askOrDesc) : null;
+                children = new ArrayList<>();
 
-                if (desc != null) {
-                    if (desc)
-                        descFields.put(col, dataType);
-                    else
-                        ascFields.put(col, dataType);
-                }
-
-                idxCols.put(col, new IgniteBiTuple<Class<?>, Boolean>(dataType, desc));
+                parents.put(schema, parent);
+                childrens.put(schema, children);
             }
-        }
 
-        return new PojoDescriptor(parent, typeMeta, fields);
-    }
-
-    /**
-     * Parse database metadata.
-     *
-     * @param conn Connection to database.
-     * @param tblsOnly If {@code true} then process tables only else process tables and views.
-     * @return Map with schemes and tables metadata.
-     * @throws SQLException If parsing failed.
-     */
-    public static ObservableList<PojoDescriptor> parse(Connection conn, boolean tblsOnly) throws SQLException {
-        DatabaseMetaData dbMeta = conn.getMetaData();
+            children.add(new PojoDescriptor(parent, tbl));
+        }
 
         List<PojoDescriptor> res = new ArrayList<>();
 
-        try (ResultSet schemas = dbMeta.getSchemas()) {
-            while (schemas.next()) {
-                String schema = schemas.getString(1);
-
-                // Skip system tables from INFORMATION_SCHEMA.
-                if ("INFORMATION_SCHEMA".equalsIgnoreCase(schema))
-                    continue;
-
-                String catalog = schemas.getString(2);
-
-                PojoDescriptor parent = PojoDescriptor.schema(schema);
-
-                List<PojoDescriptor> children = new ArrayList<>();
-
-                try (ResultSet tbls = dbMeta.getTables(catalog, schema, "%", null)) {
-                    while (tbls.next()) {
-                        String tblType = tbls.getString(4);
-
-                        if ("TABLE".equals(tblType) || (!tblsOnly && "VIEW".equals(tblType)))
-                            children.add(parseTable(parent, dbMeta, catalog, schema, tbls.getString(3)));
-                    }
-                }
+        for (String schema : parents.keySet()) {
+            PojoDescriptor parent = parents.get(schema);
+            Collection<PojoDescriptor> children = childrens.get(schema);
 
-                if (!children.isEmpty()) {
-                    parent.children(children);
+            if (!children.isEmpty()) {
+                parent.children(children);
 
-                    res.add(parent);
-                    res.addAll(children);
-                }
+                res.add(parent);
+                res.addAll(children);
             }
         }