This is an automated email from the ASF dual-hosted git repository.

dschneider pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/geode.git


The following commit(s) were added to refs/heads/develop by this push:
     new 56c3593  GEODE-6156: add --id option to create jdbc-mapping (#2969)
56c3593 is described below

commit 56c35934241500e5afc30a347c969f6abe43920c
Author: Darrel Schneider <[email protected]>
AuthorDate: Tue Dec 11 13:27:42 2018 -0800

    GEODE-6156: add --id option to create jdbc-mapping (#2969)
---
 .../TableMetaDataManagerIntegrationTest.java       |  50 ++++++--
 .../jdbc/internal/TestConfigService.java           |   2 +-
 .../cli/CreateMappingCommandDUnitTest.java         |   6 +-
 .../cli/DescribeMappingCommandDUnitTest.java       |   6 +-
 .../internal/cli/ListMappingCommandDUnitTest.java  |   2 +-
 .../geode/connectors/jdbc/internal/SqlHandler.java |   4 +-
 .../jdbc/internal/TableMetaDataManager.java        |  40 +++++-
 .../jdbc/internal/cli/CreateMappingCommand.java    |   9 +-
 .../jdbc/internal/cli/DescribeMappingCommand.java  |   2 +
 .../jdbc/internal/configuration/RegionMapping.java |  28 ++++-
 .../connectors/jdbc/internal/xml/ElementType.java  |   1 +
 .../xml/JdbcConnectorServiceXmlParser.java         |   1 +
 .../geode.apache.org/schema/jdbc/jdbc-1.0.xsd      |   1 +
 .../sanctioned-geode-connectors-serializables.txt  |   2 +-
 .../jdbc/internal/RegionMappingTest.java           |  73 +++++++----
 .../connectors/jdbc/internal/SqlHandlerTest.java   |   4 +-
 .../jdbc/internal/TableMetaDataManagerTest.java    | 139 +++++++++++++++++----
 .../internal/cli/CreateMappingCommandTest.java     |  22 ++--
 .../internal/cli/CreateMappingFunctionTest.java    |   2 +-
 .../internal/cli/DescribeMappingCommandTest.java   |  11 +-
 .../jdbc/internal/cli/ListMappingCommandTest.java  |   4 +-
 .../jdbc/internal/xml/ElementTypeTest.java         |   3 +
 22 files changed, 313 insertions(+), 99 deletions(-)

diff --git 
a/geode-connectors/src/acceptanceTest/java/org/apache/geode/connectors/jdbc/internal/TableMetaDataManagerIntegrationTest.java
 
b/geode-connectors/src/acceptanceTest/java/org/apache/geode/connectors/jdbc/internal/TableMetaDataManagerIntegrationTest.java
index 2136f4a..399229c 100644
--- 
a/geode-connectors/src/acceptanceTest/java/org/apache/geode/connectors/jdbc/internal/TableMetaDataManagerIntegrationTest.java
+++ 
b/geode-connectors/src/acceptanceTest/java/org/apache/geode/connectors/jdbc/internal/TableMetaDataManagerIntegrationTest.java
@@ -42,7 +42,6 @@ public abstract class TableMetaDataManagerIntegrationTest {
   public void setup() throws Exception {
     connection = getConnection();
     statement = connection.createStatement();
-    createTable();
     manager = new TableMetaDataManager();
   }
 
@@ -71,12 +70,20 @@ public abstract class TableMetaDataManagerIntegrationTest {
     statement.execute("CREATE TABLE " + REGION_TABLE_NAME + " (" + quote + 
"id" + quote
         + " VARCHAR(10) primary key not null," + quote + "name" + quote + " 
VARCHAR(10)," + quote
         + "age" + quote + " int)");
+  }
 
+  protected void createTableWithNoPrimaryKey() throws SQLException {
+    DatabaseMetaData metaData = connection.getMetaData();
+    String quote = metaData.getIdentifierQuoteString();
+    statement.execute("CREATE TABLE " + REGION_TABLE_NAME + " (" + quote + 
"nonprimaryid" + quote
+        + " VARCHAR(10)," + quote + "name" + quote + " VARCHAR(10)," + quote
+        + "age" + quote + " int)");
   }
 
   @Test
-  public void validateKeyColumnName() {
-    TableMetaDataView metaData = manager.getTableMetaDataView(connection, 
REGION_TABLE_NAME);
+  public void validateKeyColumnName() throws SQLException {
+    createTable();
+    TableMetaDataView metaData = manager.getTableMetaDataView(connection, 
REGION_TABLE_NAME, null);
 
     String keyColumnName = metaData.getKeyColumnName();
 
@@ -84,8 +91,31 @@ public abstract class TableMetaDataManagerIntegrationTest {
   }
 
   @Test
-  public void validateColumnDataTypeForName() {
-    TableMetaDataView metaData = manager.getTableMetaDataView(connection, 
REGION_TABLE_NAME);
+  public void validateKeyColumnNameOnNonPrimaryKey() throws SQLException {
+    createTableWithNoPrimaryKey();
+    TableMetaDataView metaData =
+        manager.getTableMetaDataView(connection, REGION_TABLE_NAME, 
"nonprimaryid");
+
+    String keyColumnName = metaData.getKeyColumnName();
+
+    assertThat(keyColumnName).isEqualTo("nonprimaryid");
+  }
+
+  @Test
+  public void validateKeyColumnNameOnNonPrimaryKeyWithInExactMatch() throws 
SQLException {
+    createTableWithNoPrimaryKey();
+    TableMetaDataView metaData =
+        manager.getTableMetaDataView(connection, REGION_TABLE_NAME, 
"NonPrimaryId");
+
+    String keyColumnName = metaData.getKeyColumnName();
+
+    assertThat(keyColumnName).isEqualTo("NonPrimaryId");
+  }
+
+  @Test
+  public void validateColumnDataTypeForName() throws SQLException {
+    createTable();
+    TableMetaDataView metaData = manager.getTableMetaDataView(connection, 
REGION_TABLE_NAME, null);
 
     int nameDataType = metaData.getColumnDataType("name");
 
@@ -93,8 +123,9 @@ public abstract class TableMetaDataManagerIntegrationTest {
   }
 
   @Test
-  public void validateColumnDataTypeForId() {
-    TableMetaDataView metaData = manager.getTableMetaDataView(connection, 
REGION_TABLE_NAME);
+  public void validateColumnDataTypeForId() throws SQLException {
+    createTable();
+    TableMetaDataView metaData = manager.getTableMetaDataView(connection, 
REGION_TABLE_NAME, null);
 
     int nameDataType = metaData.getColumnDataType("id");
 
@@ -102,8 +133,9 @@ public abstract class TableMetaDataManagerIntegrationTest {
   }
 
   @Test
-  public void validateColumnDataTypeForAge() {
-    TableMetaDataView metaData = manager.getTableMetaDataView(connection, 
REGION_TABLE_NAME);
+  public void validateColumnDataTypeForAge() throws SQLException {
+    createTable();
+    TableMetaDataView metaData = manager.getTableMetaDataView(connection, 
REGION_TABLE_NAME, null);
 
     int nameDataType = metaData.getColumnDataType("age");
 
diff --git 
a/geode-connectors/src/acceptanceTest/java/org/apache/geode/connectors/jdbc/internal/TestConfigService.java
 
b/geode-connectors/src/acceptanceTest/java/org/apache/geode/connectors/jdbc/internal/TestConfigService.java
index 2f561f9..2441ae8 100644
--- 
a/geode-connectors/src/acceptanceTest/java/org/apache/geode/connectors/jdbc/internal/TestConfigService.java
+++ 
b/geode-connectors/src/acceptanceTest/java/org/apache/geode/connectors/jdbc/internal/TestConfigService.java
@@ -52,6 +52,6 @@ public class TestConfigService {
 
   private static RegionMapping createRegionMapping(String pdxClassName) {
     return new RegionMapping(REGION_NAME, pdxClassName, REGION_TABLE_NAME,
-        CONNECTION_CONFIG_NAME);
+        CONNECTION_CONFIG_NAME, null);
   }
 }
diff --git 
a/geode-connectors/src/distributedTest/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingCommandDUnitTest.java
 
b/geode-connectors/src/distributedTest/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingCommandDUnitTest.java
index 2bd74ef..21b48e2 100644
--- 
a/geode-connectors/src/distributedTest/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingCommandDUnitTest.java
+++ 
b/geode-connectors/src/distributedTest/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingCommandDUnitTest.java
@@ -16,6 +16,7 @@ package org.apache.geode.connectors.jdbc.internal.cli;
 
 import static 
org.apache.geode.connectors.jdbc.internal.cli.CreateMappingCommand.CREATE_MAPPING;
 import static 
org.apache.geode.connectors.jdbc.internal.cli.CreateMappingCommand.CREATE_MAPPING__DATA_SOURCE_NAME;
+import static 
org.apache.geode.connectors.jdbc.internal.cli.CreateMappingCommand.CREATE_MAPPING__ID_NAME;
 import static 
org.apache.geode.connectors.jdbc.internal.cli.CreateMappingCommand.CREATE_MAPPING__PDX_NAME;
 import static 
org.apache.geode.connectors.jdbc.internal.cli.CreateMappingCommand.CREATE_MAPPING__REGION_NAME;
 import static 
org.apache.geode.connectors.jdbc.internal.cli.CreateMappingCommand.CREATE_MAPPING__SYNCHRONOUS_NAME;
@@ -183,6 +184,7 @@ public class CreateMappingCommandDUnitTest {
     csb.addOption(CREATE_MAPPING__DATA_SOURCE_NAME, "connection");
     csb.addOption(CREATE_MAPPING__TABLE_NAME, "myTable");
     csb.addOption(CREATE_MAPPING__PDX_NAME, "myPdxClass");
+    csb.addOption(CREATE_MAPPING__ID_NAME, "myId");
 
     gfsh.executeAndAssertThat(csb.toString()).statusIsSuccess();
 
@@ -191,6 +193,7 @@ public class CreateMappingCommandDUnitTest {
       assertThat(mapping.getDataSourceName()).isEqualTo("connection");
       assertThat(mapping.getTableName()).isEqualTo("myTable");
       assertThat(mapping.getPdxName()).isEqualTo("myPdxClass");
+      assertThat(mapping.getIds()).isEqualTo("myId");
       validateRegionAlteredOnServer(regionName, false);
       validateAsyncEventQueueCreatedOnServer(regionName, false);
     });
@@ -200,6 +203,7 @@ public class CreateMappingCommandDUnitTest {
       assertThat(regionMapping.getDataSourceName()).isEqualTo("connection");
       assertThat(regionMapping.getTableName()).isEqualTo("myTable");
       assertThat(regionMapping.getPdxName()).isEqualTo("myPdxClass");
+      assertThat(regionMapping.getIds()).isEqualTo("myId");
       validateRegionAlteredInClusterConfig(regionName, false);
       validateAsyncEventQueueCreatedInClusterConfig(regionName, false);
     });
@@ -342,7 +346,7 @@ public class CreateMappingCommandDUnitTest {
     // NOTE: --table is optional so it should not be in the output but it is. 
See GEODE-3468.
     gfsh.executeAndAssertThat(csb.toString()).statusIsError()
         .containsOutput(
-            "You should specify option (--table, --pdx-name, --synchronous) 
for this command");
+            "You should specify option (--table, --pdx-name, --synchronous, 
--id) for this command");
   }
 
   @Test
diff --git 
a/geode-connectors/src/distributedTest/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeMappingCommandDUnitTest.java
 
b/geode-connectors/src/distributedTest/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeMappingCommandDUnitTest.java
index d21227e..8490e42 100644
--- 
a/geode-connectors/src/distributedTest/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeMappingCommandDUnitTest.java
+++ 
b/geode-connectors/src/distributedTest/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeMappingCommandDUnitTest.java
@@ -16,6 +16,7 @@ package org.apache.geode.connectors.jdbc.internal.cli;
 
 import static 
org.apache.geode.connectors.jdbc.internal.cli.CreateMappingCommand.CREATE_MAPPING;
 import static 
org.apache.geode.connectors.jdbc.internal.cli.CreateMappingCommand.CREATE_MAPPING__DATA_SOURCE_NAME;
+import static 
org.apache.geode.connectors.jdbc.internal.cli.CreateMappingCommand.CREATE_MAPPING__ID_NAME;
 import static 
org.apache.geode.connectors.jdbc.internal.cli.CreateMappingCommand.CREATE_MAPPING__PDX_NAME;
 import static 
org.apache.geode.connectors.jdbc.internal.cli.CreateMappingCommand.CREATE_MAPPING__REGION_NAME;
 import static 
org.apache.geode.connectors.jdbc.internal.cli.CreateMappingCommand.CREATE_MAPPING__TABLE_NAME;
@@ -85,6 +86,7 @@ public class DescribeMappingCommandDUnitTest implements 
Serializable {
     csb.addOption(CREATE_MAPPING__DATA_SOURCE_NAME, "connection");
     csb.addOption(CREATE_MAPPING__TABLE_NAME, "testTable");
     csb.addOption(CREATE_MAPPING__PDX_NAME, "myPdxClass");
+    csb.addOption(CREATE_MAPPING__ID_NAME, "myId");
 
     gfsh.executeAndAssertThat(csb.toString()).statusIsSuccess();
 
@@ -99,6 +101,7 @@ public class DescribeMappingCommandDUnitTest implements 
Serializable {
     commandResultAssert.containsKeyValuePair(CREATE_MAPPING__DATA_SOURCE_NAME, 
"connection");
     commandResultAssert.containsKeyValuePair(CREATE_MAPPING__TABLE_NAME, 
"testTable");
     commandResultAssert.containsKeyValuePair(CREATE_MAPPING__PDX_NAME, 
"myPdxClass");
+    commandResultAssert.containsKeyValuePair(CREATE_MAPPING__ID_NAME, "myId");
   }
 
   @Test
@@ -139,13 +142,14 @@ public class DescribeMappingCommandDUnitTest implements 
Serializable {
     commandResultAssert.containsKeyValuePair(CREATE_MAPPING__DATA_SOURCE_NAME, 
"connection");
     commandResultAssert.containsKeyValuePair(CREATE_MAPPING__TABLE_NAME, 
"testTable");
     commandResultAssert.containsKeyValuePair(CREATE_MAPPING__PDX_NAME, 
"myPdxClass");
+    commandResultAssert.containsKeyValuePair(CREATE_MAPPING__ID_NAME, "myId");
   }
 
   private void createRegionMapping() throws RegionMappingExistsException {
     InternalCache cache = ClusterStartupRule.getCache();
     JdbcConnectorService service = 
cache.getService(JdbcConnectorService.class);
     service.createRegionMapping(new RegionMapping(REGION_NAME, "myPdxClass",
-        "testTable", "connection"));
+        "testTable", "connection", "myId"));
     assertThat(service.getMappingForRegion(REGION_NAME)).isNotNull();
   }
 }
diff --git 
a/geode-connectors/src/distributedTest/java/org/apache/geode/connectors/jdbc/internal/cli/ListMappingCommandDUnitTest.java
 
b/geode-connectors/src/distributedTest/java/org/apache/geode/connectors/jdbc/internal/cli/ListMappingCommandDUnitTest.java
index 00cc454..6cfd1bc 100644
--- 
a/geode-connectors/src/distributedTest/java/org/apache/geode/connectors/jdbc/internal/cli/ListMappingCommandDUnitTest.java
+++ 
b/geode-connectors/src/distributedTest/java/org/apache/geode/connectors/jdbc/internal/cli/ListMappingCommandDUnitTest.java
@@ -116,7 +116,7 @@ public class ListMappingCommandDUnitTest implements 
Serializable {
     for (int i = 1; i <= N; i++) {
       String name = regionName + "-" + i;
       service.createRegionMapping(
-          new RegionMapping(name, "x.y.MyPdxClass", "table", "connection"));
+          new RegionMapping(name, "x.y.MyPdxClass", "table", "connection", 
null));
       assertThat(service.getMappingForRegion(name)).isNotNull();
     }
   }
diff --git 
a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/SqlHandler.java
 
b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/SqlHandler.java
index 5d46e73..9335d03 100644
--- 
a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/SqlHandler.java
+++ 
b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/SqlHandler.java
@@ -76,7 +76,7 @@ public class SqlHandler {
     PdxInstance result;
     try (Connection connection = 
getConnection(regionMapping.getDataSourceName())) {
       TableMetaDataView tableMetaData = 
this.tableMetaDataManager.getTableMetaDataView(connection,
-          regionMapping.getRegionToTableName());
+          regionMapping.getRegionToTableName(), regionMapping.getIds());
       EntryColumnData entryColumnData =
           getEntryColumnData(tableMetaData, regionMapping, key, null, 
Operation.GET);
       try (PreparedStatement statement =
@@ -163,7 +163,7 @@ public class SqlHandler {
 
     try (Connection connection = 
getConnection(regionMapping.getDataSourceName())) {
       TableMetaDataView tableMetaData = 
this.tableMetaDataManager.getTableMetaDataView(connection,
-          regionMapping.getRegionToTableName());
+          regionMapping.getRegionToTableName(), regionMapping.getIds());
       EntryColumnData entryColumnData =
           getEntryColumnData(tableMetaData, regionMapping, key, value, 
operation);
       int updateCount = 0;
diff --git 
a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/TableMetaDataManager.java
 
b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/TableMetaDataManager.java
index f743caa..a454d3e 100644
--- 
a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/TableMetaDataManager.java
+++ 
b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/TableMetaDataManager.java
@@ -34,18 +34,20 @@ public class TableMetaDataManager {
   private final ConcurrentMap<String, TableMetaDataView> tableToMetaDataMap =
       new ConcurrentHashMap<>();
 
-  public TableMetaDataView getTableMetaDataView(Connection connection, String 
tableName) {
+  public TableMetaDataView getTableMetaDataView(Connection connection, String 
tableName,
+      String ids) {
     return tableToMetaDataMap.computeIfAbsent(tableName,
-        k -> computeTableMetaDataView(connection, k));
+        k -> computeTableMetaDataView(connection, k, ids));
   }
 
-  private TableMetaDataView computeTableMetaDataView(Connection connection, 
String tableName) {
+  private TableMetaDataView computeTableMetaDataView(Connection connection, 
String tableName,
+      String ids) {
     TableMetaData result;
     try {
       DatabaseMetaData metaData = connection.getMetaData();
       try (ResultSet tables = metaData.getTables(null, null, "%", null)) {
         String realTableName = getTableNameFromMetaData(tableName, tables);
-        String key = getPrimaryKeyColumnNameFromMetaData(realTableName, 
metaData);
+        String key = getPrimaryKeyColumnNameFromMetaData(realTableName, 
metaData, ids);
         String quoteString = metaData.getIdentifierQuoteString();
         if (quoteString == null) {
           quoteString = "";
@@ -83,8 +85,16 @@ public class TableMetaDataManager {
     return result;
   }
 
-  private String getPrimaryKeyColumnNameFromMetaData(String tableName, 
DatabaseMetaData metaData)
+  private String getPrimaryKeyColumnNameFromMetaData(String tableName, 
DatabaseMetaData metaData,
+      String ids)
       throws SQLException {
+    if (ids != null && !ids.isEmpty()) {
+      if (!doesColumnExistInTable(tableName, metaData, ids)) {
+        throw new JdbcConnectorException(
+            "The table " + tableName + " does not have a column named " + ids);
+      }
+      return ids;
+    }
     try (ResultSet primaryKeys = metaData.getPrimaryKeys(null, null, 
tableName)) {
       if (!primaryKeys.next()) {
         throw new JdbcConnectorException(
@@ -109,4 +119,24 @@ public class TableMetaDataManager {
       }
     }
   }
+
+  private boolean doesColumnExistInTable(String tableName, DatabaseMetaData 
metaData,
+      String columnName) throws SQLException {
+    int caseInsensitiveMatches = 0;
+    try (ResultSet columnData = metaData.getColumns(null, null, tableName, 
"%")) {
+      while (columnData.next()) {
+        String realColumnName = columnData.getString("COLUMN_NAME");
+        if (columnName.equals(realColumnName)) {
+          return true;
+        } else if (columnName.equalsIgnoreCase(realColumnName)) {
+          caseInsensitiveMatches++;
+        }
+      }
+    }
+    if (caseInsensitiveMatches > 1) {
+      throw new JdbcConnectorException(
+          "The table " + tableName + " has more than one column that matches " 
+ columnName);
+    }
+    return caseInsensitiveMatches != 0;
+  }
 }
diff --git 
a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingCommand.java
 
b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingCommand.java
index 5515f42..6bcefc5 100644
--- 
a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingCommand.java
+++ 
b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingCommand.java
@@ -63,6 +63,9 @@ public class CreateMappingCommand extends SingleGfshCommand {
   static final String CREATE_MAPPING__SYNCHRONOUS_NAME = "synchronous";
   static final String CREATE_MAPPING__SYNCHRONOUS_NAME__HELP =
       "By default, writes will be asynchronous. If true, writes will be 
synchronous.";
+  static final String CREATE_MAPPING__ID_NAME = "id";
+  static final String CREATE_MAPPING__ID_NAME__HELP =
+      "The table column name to use as the region key for this JDBC mapping.";
 
   public static String createAsyncEventQueueName(String regionPath) {
     if (regionPath.startsWith("/")) {
@@ -86,14 +89,16 @@ public class CreateMappingCommand extends SingleGfshCommand 
{
           help = CREATE_MAPPING__PDX_NAME__HELP) String pdxName,
       @CliOption(key = CREATE_MAPPING__SYNCHRONOUS_NAME,
           help = CREATE_MAPPING__SYNCHRONOUS_NAME__HELP,
-          specifiedDefaultValue = "true", unspecifiedDefaultValue = "false") 
boolean synchronous) {
+          specifiedDefaultValue = "true", unspecifiedDefaultValue = "false") 
boolean synchronous,
+      @CliOption(key = CREATE_MAPPING__ID_NAME,
+          help = CREATE_MAPPING__ID_NAME__HELP) String id) {
     if (regionName.startsWith("/")) {
       regionName = regionName.substring(1);
     }
 
     // input
     Set<DistributedMember> targetMembers = getMembers(null, null);
-    RegionMapping mapping = new RegionMapping(regionName, pdxName, table, 
dataSourceName);
+    RegionMapping mapping = new RegionMapping(regionName, pdxName, table, 
dataSourceName, id);
 
     try {
       ConfigurationPersistenceService configurationPersistenceService =
diff --git 
a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeMappingCommand.java
 
b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeMappingCommand.java
index cb589c8..038c31c 100644
--- 
a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeMappingCommand.java
+++ 
b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeMappingCommand.java
@@ -15,6 +15,7 @@
 package org.apache.geode.connectors.jdbc.internal.cli;
 
 import static 
org.apache.geode.connectors.jdbc.internal.cli.CreateMappingCommand.CREATE_MAPPING__DATA_SOURCE_NAME;
+import static 
org.apache.geode.connectors.jdbc.internal.cli.CreateMappingCommand.CREATE_MAPPING__ID_NAME;
 import static 
org.apache.geode.connectors.jdbc.internal.cli.CreateMappingCommand.CREATE_MAPPING__PDX_NAME;
 import static 
org.apache.geode.connectors.jdbc.internal.cli.CreateMappingCommand.CREATE_MAPPING__REGION_NAME;
 import static 
org.apache.geode.connectors.jdbc.internal.cli.CreateMappingCommand.CREATE_MAPPING__TABLE_NAME;
@@ -89,6 +90,7 @@ public class DescribeMappingCommand extends GfshCommand {
     sectionModel.addData(CREATE_MAPPING__DATA_SOURCE_NAME, 
mapping.getDataSourceName());
     sectionModel.addData(CREATE_MAPPING__TABLE_NAME, mapping.getTableName());
     sectionModel.addData(CREATE_MAPPING__PDX_NAME, mapping.getPdxName());
+    sectionModel.addData(CREATE_MAPPING__ID_NAME, mapping.getIds());
   }
 
   @CliAvailabilityIndicator({DESCRIBE_MAPPING})
diff --git 
a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/configuration/RegionMapping.java
 
b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/configuration/RegionMapping.java
index 7dfebeb..28bbacb 100644
--- 
a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/configuration/RegionMapping.java
+++ 
b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/configuration/RegionMapping.java
@@ -48,6 +48,7 @@ import org.apache.geode.pdx.internal.TypeRegistry;
  *       &lt;attribute name="data-source" 
type="{http://www.w3.org/2001/XMLSchema}string"; />
  *       &lt;attribute name="table" 
type="{http://www.w3.org/2001/XMLSchema}string"; />
  *       &lt;attribute name="pdx-name" 
type="{http://www.w3.org/2001/XMLSchema}string"; />
+ *       &lt;attribute name="ids" 
type="{http://www.w3.org/2001/XMLSchema}string"; />
  *     &lt;/restriction>
  *   &lt;/complexContent>
  * &lt;/complexType>
@@ -69,6 +70,8 @@ public class RegionMapping implements CacheElement {
   protected String tableName;
   @XmlAttribute(name = "pdx-name")
   protected String pdxName;
+  @XmlAttribute(name = "ids")
+  protected String ids;
 
   @XmlTransient
   protected String regionName;
@@ -78,11 +81,12 @@ public class RegionMapping implements CacheElement {
   public RegionMapping() {}
 
   public RegionMapping(String regionName, String pdxName, String tableName,
-      String dataSourceName) {
+      String dataSourceName, String ids) {
     this.regionName = regionName;
     this.pdxName = pdxName;
     this.tableName = tableName;
     this.dataSourceName = dataSourceName;
+    this.ids = ids;
   }
 
   public void setDataSourceName(String dataSourceName) {
@@ -101,6 +105,10 @@ public class RegionMapping implements CacheElement {
     this.pdxName = pdxName;
   }
 
+  public void setIds(String ids) {
+    this.ids = ids;
+  }
+
   public String getDataSourceName() {
     return dataSourceName;
   }
@@ -113,6 +121,10 @@ public class RegionMapping implements CacheElement {
     return pdxName;
   }
 
+  public String getIds() {
+    return ids;
+  }
+
   public String getTableName() {
     return tableName;
   }
@@ -230,6 +242,9 @@ public class RegionMapping implements CacheElement {
         : that.dataSourceName != null) {
       return false;
     }
+    if (ids != null ? !ids.equals(that.ids) : that.ids != null) {
+      return false;
+    }
     return true;
   }
 
@@ -239,14 +254,19 @@ public class RegionMapping implements CacheElement {
     result = 31 * result + pdxName.hashCode();
     result = 31 * result + (tableName != null ? tableName.hashCode() : 0);
     result = 31 * result + (dataSourceName != null ? dataSourceName.hashCode() 
: 0);
+    result = 31 * result + (ids != null ? ids.hashCode() : 0);
     return result;
   }
 
   @Override
   public String toString() {
-    return "RegionMapping{" + "regionName='" + regionName + '\'' + ", 
pdxName='"
-        + pdxName + '\'' + ", tableName='" + tableName + '\'' + ", 
dataSourceName='"
-        + dataSourceName + '\'' + '}';
+    return "RegionMapping{"
+        + "regionName='" + regionName + '\''
+        + ", pdxName='" + pdxName + '\''
+        + ", tableName='" + tableName + '\''
+        + ", dataSourceName='" + dataSourceName + '\''
+        + ", ids='" + ids + '\''
+        + '}';
   }
 
   @Override
diff --git 
a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/xml/ElementType.java
 
b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/xml/ElementType.java
index 7379d61..46eca88 100644
--- 
a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/xml/ElementType.java
+++ 
b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/xml/ElementType.java
@@ -37,6 +37,7 @@ public enum ElementType {
           attributes.getValue(JdbcConnectorServiceXmlParser.DATA_SOURCE));
       
mapping.setTableName(attributes.getValue(JdbcConnectorServiceXmlParser.TABLE));
       
mapping.setPdxName(attributes.getValue(JdbcConnectorServiceXmlParser.PDX_NAME));
+      mapping.setIds(attributes.getValue(JdbcConnectorServiceXmlParser.IDS));
       stack.push(mapping);
     }
 
diff --git 
a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/xml/JdbcConnectorServiceXmlParser.java
 
b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/xml/JdbcConnectorServiceXmlParser.java
index c2e7d36..abef62c 100644
--- 
a/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/xml/JdbcConnectorServiceXmlParser.java
+++ 
b/geode-connectors/src/main/java/org/apache/geode/connectors/jdbc/internal/xml/JdbcConnectorServiceXmlParser.java
@@ -24,6 +24,7 @@ public class JdbcConnectorServiceXmlParser extends 
AbstractXmlParser {
   static final String DATA_SOURCE = "data-source";
   static final String TABLE = "table";
   static final String PDX_NAME = "pdx-name";
+  static final String IDS = "ids";
 
   @Override
   public String getNamespaceUri() {
diff --git 
a/geode-connectors/src/main/resources/META-INF/schemas/geode.apache.org/schema/jdbc/jdbc-1.0.xsd
 
b/geode-connectors/src/main/resources/META-INF/schemas/geode.apache.org/schema/jdbc/jdbc-1.0.xsd
index 7082812..b225a4d 100644
--- 
a/geode-connectors/src/main/resources/META-INF/schemas/geode.apache.org/schema/jdbc/jdbc-1.0.xsd
+++ 
b/geode-connectors/src/main/resources/META-INF/schemas/geode.apache.org/schema/jdbc/jdbc-1.0.xsd
@@ -43,6 +43,7 @@ XML schema for JDBC Connector Service in Geode.
                 <xsd:attribute type="xsd:string" name="data-source" 
use="required"/>
                 <xsd:attribute type="xsd:string" name="table" use="optional"/>
                 <xsd:attribute type="xsd:string" name="pdx-name" 
use="required"/>
+                <xsd:attribute type="xsd:string" name="ids" use="optional"/>
             </xsd:complexType>
         </xsd:element>
 </xsd:schema>
diff --git 
a/geode-connectors/src/main/resources/org/apache/geode/internal/sanctioned-geode-connectors-serializables.txt
 
b/geode-connectors/src/main/resources/org/apache/geode/internal/sanctioned-geode-connectors-serializables.txt
index 8c6a4af..de159fb 100755
--- 
a/geode-connectors/src/main/resources/org/apache/geode/internal/sanctioned-geode-connectors-serializables.txt
+++ 
b/geode-connectors/src/main/resources/org/apache/geode/internal/sanctioned-geode-connectors-serializables.txt
@@ -5,4 +5,4 @@ 
org/apache/geode/connectors/jdbc/internal/cli/CreateMappingFunction,false
 org/apache/geode/connectors/jdbc/internal/cli/DescribeMappingFunction,false
 org/apache/geode/connectors/jdbc/internal/cli/DestroyMappingFunction,false
 org/apache/geode/connectors/jdbc/internal/cli/ListMappingFunction,false
-org/apache/geode/connectors/jdbc/internal/configuration/RegionMapping,false,dataSourceName:java/lang/String,pdxName:java/lang/String,regionName:java/lang/String,tableName:java/lang/String
+org/apache/geode/connectors/jdbc/internal/configuration/RegionMapping,false,dataSourceName:java/lang/String,ids:java/lang/String,pdxName:java/lang/String,regionName:java/lang/String,tableName:java/lang/String
diff --git 
a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/RegionMappingTest.java
 
b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/RegionMappingTest.java
index f84b9c0..4eee89f 100644
--- 
a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/RegionMappingTest.java
+++ 
b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/RegionMappingTest.java
@@ -57,20 +57,21 @@ public class RegionMappingTest {
 
   @Test
   public void initiatedWithNullValues() {
-    mapping = new RegionMapping(null, "pdxClassName", null, null);
+    mapping = new RegionMapping(null, "pdxClassName", null, null, null);
 
     assertThat(mapping.getTableName()).isNull();
     assertThat(mapping.getRegionName()).isNull();
     assertThat(mapping.getDataSourceName()).isNull();
     assertThat(mapping.getPdxName()).isEqualTo("pdxClassName");
     assertThat(mapping.getRegionToTableName()).isNull();
+    assertThat(mapping.getIds()).isNull();
     assertThat(mapping.getColumnNameForField("fieldName", 
mock(TableMetaDataView.class)))
         .isEqualTo("fieldName");
   }
 
   @Test
   public void hasCorrectTableName() {
-    mapping = new RegionMapping(null, null, name, null);
+    mapping = new RegionMapping(null, null, name, null, null);
 
     assertThat(mapping.getTableName()).isEqualTo(name);
     assertThat(mapping.getRegionToTableName()).isEqualTo(name);
@@ -78,7 +79,7 @@ public class RegionMappingTest {
 
   @Test
   public void hasCorrectTableNameWhenRegionNameIsSet() {
-    mapping = new RegionMapping("regionName", null, "tableName", null);
+    mapping = new RegionMapping("regionName", null, "tableName", null, null);
 
     assertThat(mapping.getRegionName()).isEqualTo("regionName");
     assertThat(mapping.getTableName()).isEqualTo("tableName");
@@ -87,7 +88,7 @@ public class RegionMappingTest {
 
   @Test
   public void hasCorrectRegionName() {
-    mapping = new RegionMapping(name, null, null, null);
+    mapping = new RegionMapping(name, null, null, null, null);
 
     assertThat(mapping.getRegionName()).isEqualTo(name);
     assertThat(mapping.getRegionToTableName()).isEqualTo(name);
@@ -95,21 +96,29 @@ public class RegionMappingTest {
 
   @Test
   public void hasCorrectConfigName() {
-    mapping = new RegionMapping(null, null, null, name);
+    mapping = new RegionMapping(null, null, null, name, null);
 
     assertThat(mapping.getDataSourceName()).isEqualTo(name);
   }
 
   @Test
   public void hasCorrectPdxClassName() {
-    mapping = new RegionMapping(null, name, null, null);
+    mapping = new RegionMapping(null, name, null, null, null);
 
     assertThat(mapping.getPdxName()).isEqualTo(name);
   }
 
   @Test
+  public void hasCorrectIds() {
+    String ids = "ids";
+    mapping = new RegionMapping(null, null, null, null, ids);
+
+    assertThat(mapping.getIds()).isEqualTo(ids);
+  }
+
+  @Test
   public void returnsColumnNameIfFieldNotMapped() {
-    mapping = new RegionMapping(null, "pdxClassName", null, null);
+    mapping = new RegionMapping(null, "pdxClassName", null, null, null);
 
     String columnName = mapping.getColumnNameForField(fieldName1, 
mock(TableMetaDataView.class));
 
@@ -119,7 +128,7 @@ public class RegionMappingTest {
   @Test
   public void 
returnsColumnNameFromTableMetaDataIfFieldNotMappedAndMetaDataMatchesWithCaseDiffering()
 {
     String metaDataColumnName = fieldName1.toUpperCase();
-    mapping = new RegionMapping(null, "pdxClassName", null, null);
+    mapping = new RegionMapping(null, "pdxClassName", null, null, null);
     TableMetaDataView tableMetaDataView = mock(TableMetaDataView.class);
     
when(tableMetaDataView.getColumnNames()).thenReturn(Collections.singleton(metaDataColumnName));
 
@@ -130,7 +139,7 @@ public class RegionMappingTest {
   @Test
   public void 
returnsColumnNameFromTableMetaDataIfFieldNotMappedAndMetaDataMatchesExactly() {
     String metaDataColumnName = fieldName1;
-    mapping = new RegionMapping(null, "pdxClassName", null, null);
+    mapping = new RegionMapping(null, "pdxClassName", null, null, null);
     TableMetaDataView tableMetaDataView = mock(TableMetaDataView.class);
     
when(tableMetaDataView.getColumnNames()).thenReturn(Collections.singleton(metaDataColumnName));
 
@@ -140,7 +149,7 @@ public class RegionMappingTest {
 
   @Test
   public void returnsColumnNameIfFieldNotMappedAndNotInMetaData() {
-    mapping = new RegionMapping(null, "pdxClassName", null, null);
+    mapping = new RegionMapping(null, "pdxClassName", null, null, null);
     TableMetaDataView tableMetaDataView = mock(TableMetaDataView.class);
     
when(tableMetaDataView.getColumnNames()).thenReturn(Collections.singleton("does 
not match"));
 
@@ -149,7 +158,7 @@ public class RegionMappingTest {
 
   @Test
   public void getColumnNameForFieldThrowsIfTwoColumnsMatchField() {
-    mapping = new RegionMapping(null, "pdxClassName", null, null);
+    mapping = new RegionMapping(null, "pdxClassName", null, null, null);
 
     TableMetaDataView tableMetaDataView = mock(TableMetaDataView.class);
     HashSet<String> columnNames =
@@ -165,7 +174,7 @@ public class RegionMappingTest {
 
   @Test
   public void throwsIfColumnNotMappedAndPdxClassNameDoesNotExist() {
-    mapping = new RegionMapping(null, "pdxClassName", null, null);
+    mapping = new RegionMapping(null, "pdxClassName", null, null, null);
     TypeRegistry typeRegistry = mock(TypeRegistry.class);
     
when(typeRegistry.getPdxTypesForClassName("pdxClassName")).thenReturn(Collections.emptySet());
     expectedException.expect(JdbcConnectorException.class);
@@ -178,7 +187,7 @@ public class RegionMappingTest {
   public void 
throwsIfColumnNotMappedAndPdxClassNameDoesExistButHasNoMatchingFields() {
     String pdxClassName = "pdxClassName";
     String columnName = "columnName";
-    mapping = new RegionMapping(null, pdxClassName, null, null);
+    mapping = new RegionMapping(null, pdxClassName, null, null, null);
     TypeRegistry typeRegistry = mock(TypeRegistry.class);
     HashSet<PdxType> pdxTypes = new 
HashSet<>(Arrays.asList(mock(PdxType.class)));
     
when(typeRegistry.getPdxTypesForClassName(pdxClassName)).thenReturn(pdxTypes);
@@ -193,7 +202,7 @@ public class RegionMappingTest {
   public void 
throwsIfColumnNotMappedAndPdxClassNameDoesExistButHasMoreThanOneMatchingFields()
 {
     String pdxClassName = "pdxClassName";
     String columnName = "columnName";
-    mapping = new RegionMapping(null, pdxClassName, null, null);
+    mapping = new RegionMapping(null, pdxClassName, null, null, null);
     TypeRegistry typeRegistry = mock(TypeRegistry.class);
     PdxType pdxType = mock(PdxType.class);
     when(pdxType.getFieldNames())
@@ -211,7 +220,7 @@ public class RegionMappingTest {
   public void 
returnsIfColumnNotMappedAndPdxClassNameDoesExistAndHasOneFieldThatInexactlyMatches()
 {
     String pdxClassName = "pdxClassName";
     String columnName = "columnName";
-    mapping = new RegionMapping(null, pdxClassName, null, null);
+    mapping = new RegionMapping(null, pdxClassName, null, null, null);
     TypeRegistry typeRegistry = mock(TypeRegistry.class);
     PdxType pdxType = mock(PdxType.class);
     when(pdxType.getFieldNames())
@@ -227,7 +236,7 @@ public class RegionMappingTest {
   public void 
returnsIfColumnNotMappedAndPdxClassNameDoesExistAndHasOneFieldThatExactlyMatches()
 {
     String pdxClassName = "pdxClassName";
     String columnName = "columnName";
-    mapping = new RegionMapping(null, pdxClassName, null, null);
+    mapping = new RegionMapping(null, pdxClassName, null, null, null);
     TypeRegistry typeRegistry = mock(TypeRegistry.class);
     PdxType pdxType = mock(PdxType.class);
     when(pdxType.getPdxField(columnName)).thenReturn(mock(PdxField.class));
@@ -240,9 +249,9 @@ public class RegionMappingTest {
   @Test
   public void verifyTwoDefaultInstancesAreEqual() {
     RegionMapping rm1 =
-        new RegionMapping("regionName", "pdxClassName", null, 
"connectionName");
+        new RegionMapping("regionName", "pdxClassName", null, 
"dataSourceName", null);
     RegionMapping rm2 =
-        new RegionMapping("regionName", "pdxClassName", null, 
"connectionName");
+        new RegionMapping("regionName", "pdxClassName", null, 
"dataSourceName", null);
     assertThat(rm1).isEqualTo(rm2);
   }
 
@@ -250,17 +259,17 @@ public class RegionMappingTest {
   @Test
   public void verifyTwoInstancesThatAreEqualHaveSameHashCode() {
     RegionMapping rm1 = new RegionMapping("regionName",
-        "pdxClassName", "tableName", "connectionName");
+        "pdxClassName", "tableName", "dataSourceName", "ids");
 
     RegionMapping rm2 = new RegionMapping("regionName",
-        "pdxClassName", "tableName", "connectionName");
+        "pdxClassName", "tableName", "dataSourceName", "ids");
 
     assertThat(rm1.hashCode()).isEqualTo(rm2.hashCode());
   }
 
   @Test
   public void verifyThatMappingIsEqualToItself() {
-    mapping = new RegionMapping(null, "pdxClassName", null, null);
+    mapping = new RegionMapping(null, "pdxClassName", null, null, null);
     boolean result = mapping.equals(mapping);
     assertThat(mapping.hashCode()).isEqualTo(mapping.hashCode());
     assertThat(result).isTrue();
@@ -268,14 +277,14 @@ public class RegionMappingTest {
 
   @Test
   public void verifyThatNullIsNotEqual() {
-    mapping = new RegionMapping(null, null, null, null);
+    mapping = new RegionMapping(null, null, null, null, null);
     boolean result = mapping.equals(null);
     assertThat(result).isFalse();
   }
 
   @Test
   public void verifyOtherClassIsNotEqual() {
-    mapping = new RegionMapping(null, null, null, null);
+    mapping = new RegionMapping(null, null, null, null, null);
     boolean result = mapping.equals("not equal");
     assertThat(result).isFalse();
   }
@@ -283,9 +292,9 @@ public class RegionMappingTest {
   @Test
   public void verifyMappingWithDifferentRegionNamesAreNotEqual() {
     RegionMapping rm1 =
-        new RegionMapping(null, null, null, null);
+        new RegionMapping(null, null, null, null, null);
     RegionMapping rm2 =
-        new RegionMapping("name", null, null, null);
+        new RegionMapping("name", null, null, null, null);
     boolean result = rm1.equals(rm2);
     assertThat(result).isFalse();
   }
@@ -293,9 +302,19 @@ public class RegionMappingTest {
   @Test
   public void verifyMappingWithDifferentPdxClassNameAreNotEqual() {
     RegionMapping rm1 =
-        new RegionMapping(null, "pdxClassName", null, null);
+        new RegionMapping(null, "pdxClassName", null, null, null);
+    RegionMapping rm2 =
+        new RegionMapping(null, "pdxClass", null, null, null);
+    boolean result = rm1.equals(rm2);
+    assertThat(result).isFalse();
+  }
+
+  @Test
+  public void verifyMappingWithDifferentIdsAreNotEqual() {
+    RegionMapping rm1 =
+        new RegionMapping(null, "pdxClassName", null, null, "ids1");
     RegionMapping rm2 =
-        new RegionMapping(null, "pdxClass", null, null);
+        new RegionMapping(null, "pdxClassName", null, null, "ids2");
     boolean result = rm1.equals(rm2);
     assertThat(result).isFalse();
   }
diff --git 
a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/SqlHandlerTest.java
 
b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/SqlHandlerTest.java
index 4600886..d93743f 100644
--- 
a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/SqlHandlerTest.java
+++ 
b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/SqlHandlerTest.java
@@ -91,7 +91,8 @@ public class SqlHandlerTest {
     tableMetaDataView = mock(TableMetaDataView.class);
     when(tableMetaDataView.getTableName()).thenReturn(TABLE_NAME);
     when(tableMetaDataView.getKeyColumnName()).thenReturn(KEY_COLUMN);
-    when(tableMetaDataManager.getTableMetaDataView(connection, TABLE_NAME))
+    final String IDS = "ids";
+    when(tableMetaDataManager.getTableMetaDataView(connection, TABLE_NAME, 
IDS))
         .thenReturn(tableMetaDataView);
     connectorService = mock(JdbcConnectorService.class);
     dataSourceFactory = mock(DataSourceFactory.class);
@@ -105,6 +106,7 @@ public class SqlHandlerTest {
     when(regionMapping.getDataSourceName()).thenReturn(DATA_SOURCE_NAME);
     when(regionMapping.getRegionName()).thenReturn(REGION_NAME);
     when(regionMapping.getTableName()).thenReturn(TABLE_NAME);
+    when(regionMapping.getIds()).thenReturn(IDS);
     when(regionMapping.getRegionToTableName()).thenReturn(TABLE_NAME);
     
when(connectorService.getMappingForRegion(REGION_NAME)).thenReturn(regionMapping);
 
diff --git 
a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/TableMetaDataManagerTest.java
 
b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/TableMetaDataManagerTest.java
index 9390263..91e8a73 100644
--- 
a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/TableMetaDataManagerTest.java
+++ 
b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/TableMetaDataManagerTest.java
@@ -68,17 +68,88 @@ public class TableMetaDataManagerTest {
     setupPrimaryKeysMetaData();
     when(primaryKeysResultSet.next()).thenReturn(true).thenReturn(false);
 
-    TableMetaDataView data = 
tableMetaDataManager.getTableMetaDataView(connection, TABLE_NAME);
+    TableMetaDataView data = 
tableMetaDataManager.getTableMetaDataView(connection, TABLE_NAME, "");
     assertThat(data.getKeyColumnName()).isEqualTo(KEY_COLUMN);
     verify(connection).getMetaData();
   }
 
   @Test
+  public void givenNoColumnsAndNonNullIdsThenExpectException() throws 
Exception {
+    when(tablesResultSet.next()).thenReturn(true).thenReturn(false);
+    when(tablesResultSet.getString("TABLE_NAME")).thenReturn(TABLE_NAME);
+    when(columnResultSet.next()).thenReturn(false);
+
+    assertThatThrownBy(
+        () -> tableMetaDataManager.getTableMetaDataView(connection, 
TABLE_NAME, "nonExistentId"))
+            .isInstanceOf(JdbcConnectorException.class)
+            .hasMessageContaining("The table testTable does not have a column 
named nonExistentId");
+  }
+
+  @Test
+  public void givenOneColumnAndNonNullIdsThatDoesNotMatchThenExpectException() 
throws Exception {
+    when(tablesResultSet.next()).thenReturn(true).thenReturn(false);
+    when(tablesResultSet.getString("TABLE_NAME")).thenReturn(TABLE_NAME);
+    when(columnResultSet.next()).thenReturn(true).thenReturn(false);
+    
when(columnResultSet.getString("COLUMN_NAME")).thenReturn("existingColumn");
+
+    assertThatThrownBy(
+        () -> tableMetaDataManager.getTableMetaDataView(connection, 
TABLE_NAME, "nonExistentId"))
+            .isInstanceOf(JdbcConnectorException.class)
+            .hasMessageContaining("The table testTable does not have a column 
named nonExistentId");
+  }
+
+  @Test
+  public void 
givenTwoColumnsAndNonNullIdsThatDoesNotExactlyMatchThenExpectException()
+      throws Exception {
+    when(tablesResultSet.next()).thenReturn(true).thenReturn(false);
+    when(tablesResultSet.getString("TABLE_NAME")).thenReturn(TABLE_NAME);
+    
when(columnResultSet.next()).thenReturn(true).thenReturn(true).thenReturn(false);
+    when(columnResultSet.getString("COLUMN_NAME")).thenReturn("nonexistentid")
+        .thenReturn("NONEXISTENTID");
+
+    assertThatThrownBy(
+        () -> tableMetaDataManager.getTableMetaDataView(connection, 
TABLE_NAME, "nonExistentId"))
+            .isInstanceOf(JdbcConnectorException.class).hasMessageContaining(
+                "The table testTable has more than one column that matches 
nonExistentId");
+  }
+
+  @Test
+  public void 
givenThreeColumnsAndNonNullIdsThatDoesExactlyMatchThenKeyColumnNameIsReturned()
+      throws Exception {
+    when(tablesResultSet.next()).thenReturn(true).thenReturn(false);
+    when(tablesResultSet.getString("TABLE_NAME")).thenReturn(TABLE_NAME);
+    
when(columnResultSet.next()).thenReturn(true).thenReturn(true).thenReturn(true)
+        .thenReturn(false);
+    
when(columnResultSet.getString("COLUMN_NAME")).thenReturn("existentid").thenReturn("EXISTENTID")
+        .thenReturn("ExistentId");
+
+    TableMetaDataView data =
+        tableMetaDataManager.getTableMetaDataView(connection, TABLE_NAME, 
"ExistentId");
+
+    assertThat(data.getKeyColumnName()).isEqualTo("ExistentId");
+  }
+
+  @Test
+  public void 
givenColumnAndNonNullIdsThatDoesInexactlyMatchThenKeyColumnNameIsReturned()
+      throws Exception {
+    when(tablesResultSet.next()).thenReturn(true).thenReturn(false);
+    when(tablesResultSet.getString("TABLE_NAME")).thenReturn(TABLE_NAME);
+    when(columnResultSet.next()).thenReturn(true).thenReturn(false);
+    when(columnResultSet.getString("COLUMN_NAME")).thenReturn("existentid");
+
+    TableMetaDataView data =
+        tableMetaDataManager.getTableMetaDataView(connection, TABLE_NAME, 
"ExistentId");
+
+    assertThat(data.getKeyColumnName()).isEqualTo("ExistentId");
+  }
+
+  @Test
   public void returnsDefaultQuoteString() throws Exception {
     setupPrimaryKeysMetaData();
     when(primaryKeysResultSet.next()).thenReturn(true).thenReturn(false);
 
-    TableMetaDataView data = 
tableMetaDataManager.getTableMetaDataView(connection, TABLE_NAME);
+    TableMetaDataView data =
+        tableMetaDataManager.getTableMetaDataView(connection, TABLE_NAME, 
null);
 
     assertThat(data.getIdentifierQuoteString()).isEqualTo("");
     verify(connection).getMetaData();
@@ -91,7 +162,8 @@ public class TableMetaDataManagerTest {
     String expectedQuoteString = "123";
     
when(databaseMetaData.getIdentifierQuoteString()).thenReturn(expectedQuoteString);
 
-    TableMetaDataView data = 
tableMetaDataManager.getTableMetaDataView(connection, TABLE_NAME);
+    TableMetaDataView data =
+        tableMetaDataManager.getTableMetaDataView(connection, TABLE_NAME, 
null);
 
     assertThat(data.getIdentifierQuoteString()).isEqualTo(expectedQuoteString);
     verify(connection).getMetaData();
@@ -102,8 +174,8 @@ public class TableMetaDataManagerTest {
     setupPrimaryKeysMetaData();
     when(primaryKeysResultSet.next()).thenReturn(true).thenReturn(false);
 
-    tableMetaDataManager.getTableMetaDataView(connection, TABLE_NAME);
-    tableMetaDataManager.getTableMetaDataView(connection, TABLE_NAME);
+    tableMetaDataManager.getTableMetaDataView(connection, TABLE_NAME, null);
+    tableMetaDataManager.getTableMetaDataView(connection, TABLE_NAME, null);
     verify(connection).getMetaData();
   }
 
@@ -112,8 +184,9 @@ public class TableMetaDataManagerTest {
     SQLException cause = new SQLException("sql message");
     when(connection.getMetaData()).thenThrow(cause);
 
-    assertThatThrownBy(() -> 
tableMetaDataManager.getTableMetaDataView(connection, TABLE_NAME))
-        .isInstanceOf(JdbcConnectorException.class).hasMessageContaining("sql 
message");
+    assertThatThrownBy(
+        () -> tableMetaDataManager.getTableMetaDataView(connection, 
TABLE_NAME, null))
+            
.isInstanceOf(JdbcConnectorException.class).hasMessageContaining("sql message");
   }
 
   @Test
@@ -121,9 +194,10 @@ public class TableMetaDataManagerTest {
     when(tablesResultSet.next()).thenReturn(true).thenReturn(false);
     when(tablesResultSet.getString("TABLE_NAME")).thenReturn("otherTable");
 
-    assertThatThrownBy(() -> 
tableMetaDataManager.getTableMetaDataView(connection, TABLE_NAME))
-        .isInstanceOf(JdbcConnectorException.class)
-        .hasMessage("no table was found that matches testTable");
+    assertThatThrownBy(
+        () -> tableMetaDataManager.getTableMetaDataView(connection, 
TABLE_NAME, null))
+            .isInstanceOf(JdbcConnectorException.class)
+            .hasMessage("no table was found that matches testTable");
   }
 
   @Test
@@ -131,9 +205,10 @@ public class TableMetaDataManagerTest {
     setupPrimaryKeysMetaData();
     when(primaryKeysResultSet.next()).thenReturn(true);
 
-    assertThatThrownBy(() -> 
tableMetaDataManager.getTableMetaDataView(connection, TABLE_NAME))
-        .isInstanceOf(JdbcConnectorException.class)
-        .hasMessage("The table " + TABLE_NAME + " has more than one primary 
key column.");
+    assertThatThrownBy(
+        () -> tableMetaDataManager.getTableMetaDataView(connection, 
TABLE_NAME, null))
+            .isInstanceOf(JdbcConnectorException.class)
+            .hasMessage("The table " + TABLE_NAME + " has more than one 
primary key column.");
   }
 
   @Test
@@ -144,7 +219,8 @@ public class TableMetaDataManagerTest {
     
when(tablesResultSet.getString("TABLE_NAME")).thenReturn(TABLE_NAME.toUpperCase())
         .thenReturn(TABLE_NAME);
 
-    TableMetaDataView data = 
tableMetaDataManager.getTableMetaDataView(connection, TABLE_NAME);
+    TableMetaDataView data =
+        tableMetaDataManager.getTableMetaDataView(connection, TABLE_NAME, 
null);
 
     assertThat(data.getTableName()).isEqualTo(TABLE_NAME);
   }
@@ -158,7 +234,8 @@ public class TableMetaDataManagerTest {
     when(tablesResultSet.next()).thenReturn(true).thenReturn(false);
     
when(tablesResultSet.getString("TABLE_NAME")).thenReturn(TABLE_NAME.toUpperCase());
 
-    TableMetaDataView data = 
tableMetaDataManager.getTableMetaDataView(connection, TABLE_NAME);
+    TableMetaDataView data =
+        tableMetaDataManager.getTableMetaDataView(connection, TABLE_NAME, 
null);
 
     assertThat(data.getTableName()).isEqualTo(TABLE_NAME.toUpperCase());
   }
@@ -172,9 +249,10 @@ public class TableMetaDataManagerTest {
     
when(tablesResultSet.getString("TABLE_NAME")).thenReturn(TABLE_NAME.toLowerCase())
         .thenReturn(TABLE_NAME.toUpperCase());
 
-    assertThatThrownBy(() -> 
tableMetaDataManager.getTableMetaDataView(connection, TABLE_NAME))
-        .isInstanceOf(JdbcConnectorException.class)
-        .hasMessage("Duplicate tables that match region name");
+    assertThatThrownBy(
+        () -> tableMetaDataManager.getTableMetaDataView(connection, 
TABLE_NAME, null))
+            .isInstanceOf(JdbcConnectorException.class)
+            .hasMessage("Duplicate tables that match region name");
   }
 
   @Test
@@ -182,9 +260,10 @@ public class TableMetaDataManagerTest {
     setupPrimaryKeysMetaData();
     when(primaryKeysResultSet.next()).thenReturn(false);
 
-    assertThatThrownBy(() -> 
tableMetaDataManager.getTableMetaDataView(connection, TABLE_NAME))
-        .isInstanceOf(JdbcConnectorException.class)
-        .hasMessage("The table " + TABLE_NAME + " does not have a primary key 
column.");
+    assertThatThrownBy(
+        () -> tableMetaDataManager.getTableMetaDataView(connection, 
TABLE_NAME, null))
+            .isInstanceOf(JdbcConnectorException.class)
+            .hasMessage("The table " + TABLE_NAME + " does not have a primary 
key column.");
   }
 
   @Test
@@ -192,7 +271,8 @@ public class TableMetaDataManagerTest {
     setupPrimaryKeysMetaData();
     when(primaryKeysResultSet.next()).thenReturn(true).thenReturn(false);
 
-    TableMetaDataView data = 
tableMetaDataManager.getTableMetaDataView(connection, TABLE_NAME);
+    TableMetaDataView data =
+        tableMetaDataManager.getTableMetaDataView(connection, TABLE_NAME, 
null);
     int dataType = data.getColumnDataType("unknownColumn");
 
     assertThat(dataType).isEqualTo(0);
@@ -211,7 +291,8 @@ public class TableMetaDataManagerTest {
     when(columnResultSet.getInt("DATA_TYPE")).thenReturn(columnDataType1)
         .thenReturn(columnDataType2);
 
-    TableMetaDataView data = 
tableMetaDataManager.getTableMetaDataView(connection, TABLE_NAME);
+    TableMetaDataView data =
+        tableMetaDataManager.getTableMetaDataView(connection, TABLE_NAME, 
null);
     int dataType1 = data.getColumnDataType(columnName1);
     int dataType2 = data.getColumnDataType(columnName2);
 
@@ -235,7 +316,8 @@ public class TableMetaDataManagerTest {
         .thenReturn(columnDataType2);
     Set<String> expectedColumnNames = new HashSet<>(Arrays.asList(columnName1, 
columnName2));
 
-    TableMetaDataView data = 
tableMetaDataManager.getTableMetaDataView(connection, TABLE_NAME);
+    TableMetaDataView data =
+        tableMetaDataManager.getTableMetaDataView(connection, TABLE_NAME, 
null);
     Set<String> columnNames = data.getColumnNames();
 
     assertThat(columnNames).isEqualTo(expectedColumnNames);
@@ -247,7 +329,8 @@ public class TableMetaDataManagerTest {
     setupPrimaryKeysMetaData();
     when(primaryKeysResultSet.next()).thenReturn(true).thenReturn(false);
 
-    TableMetaDataView data = 
tableMetaDataManager.getTableMetaDataView(connection, TABLE_NAME);
+    TableMetaDataView data =
+        tableMetaDataManager.getTableMetaDataView(connection, TABLE_NAME, 
null);
 
     verify(primaryKeysResultSet).close();
   }
@@ -258,7 +341,8 @@ public class TableMetaDataManagerTest {
     setupPrimaryKeysMetaData();
     when(primaryKeysResultSet.next()).thenReturn(true).thenReturn(false);
 
-    TableMetaDataView data = 
tableMetaDataManager.getTableMetaDataView(connection, TABLE_NAME);
+    TableMetaDataView data =
+        tableMetaDataManager.getTableMetaDataView(connection, TABLE_NAME, 
null);
 
     verify(columnResultSet).close();
   }
@@ -268,7 +352,8 @@ public class TableMetaDataManagerTest {
     setupPrimaryKeysMetaData();
     when(primaryKeysResultSet.next()).thenReturn(true).thenReturn(false);
 
-    TableMetaDataView data = 
tableMetaDataManager.getTableMetaDataView(connection, TABLE_NAME);
+    TableMetaDataView data =
+        tableMetaDataManager.getTableMetaDataView(connection, TABLE_NAME, 
null);
 
     assertThat(data.getTableName()).isEqualTo(TABLE_NAME);
   }
diff --git 
a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingCommandTest.java
 
b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingCommandTest.java
index 02211fa..671442d 100644
--- 
a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingCommandTest.java
+++ 
b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingCommandTest.java
@@ -120,9 +120,10 @@ public class CreateMappingCommandTest {
   public void createsMappingReturnsStatusOKWhenFunctionResultSuccess() {
     setupRequiredPreconditions();
     results.add(successFunctionResult);
+    String ids = "ids";
 
     ResultModel result = createRegionMappingCommand.createMapping(regionName, 
dataSourceName,
-        tableName, pdxClass, false);
+        tableName, pdxClass, false, ids);
 
     assertThat(result.getStatus()).isSameAs(Result.Status.OK);
     Object[] results = (Object[]) result.getConfigObject();
@@ -133,6 +134,7 @@ public class CreateMappingCommandTest {
     assertThat(regionMapping.getDataSourceName()).isEqualTo(dataSourceName);
     assertThat(regionMapping.getTableName()).isEqualTo(tableName);
     assertThat(regionMapping.getPdxName()).isEqualTo(pdxClass);
+    assertThat(regionMapping.getIds()).isEqualTo(ids);
     assertThat(synchronous).isFalse();
   }
 
@@ -142,7 +144,7 @@ public class CreateMappingCommandTest {
     results.add(successFunctionResult);
 
     ResultModel result = createRegionMappingCommand.createMapping("/" + 
regionName, dataSourceName,
-        tableName, pdxClass, false);
+        tableName, pdxClass, false, null);
 
     assertThat(result.getStatus()).isSameAs(Result.Status.OK);
     Object[] results = (Object[]) result.getConfigObject();
@@ -157,7 +159,7 @@ public class CreateMappingCommandTest {
     results.clear();
 
     ResultModel result = createRegionMappingCommand.createMapping(regionName, 
dataSourceName,
-        tableName, pdxClass, false);
+        tableName, pdxClass, false, null);
 
     assertThat(result.getStatus()).isSameAs(Result.Status.ERROR);
   }
@@ -168,7 +170,7 @@ public class CreateMappingCommandTest {
     
doReturn(null).when(createRegionMappingCommand).getConfigurationPersistenceService();
 
     ResultModel result = createRegionMappingCommand.createMapping(regionName, 
dataSourceName,
-        tableName, pdxClass, false);
+        tableName, pdxClass, false, null);
 
     assertThat(result.getStatus()).isSameAs(Result.Status.ERROR);
     assertThat(result.toString()).contains("Cluster Configuration must be 
enabled.");
@@ -185,7 +187,7 @@ public class CreateMappingCommandTest {
     when(cacheConfig.getRegions()).thenReturn(Collections.emptyList());
 
     ResultModel result = createRegionMappingCommand.createMapping(regionName, 
dataSourceName,
-        tableName, pdxClass, false);
+        tableName, pdxClass, false, null);
 
     assertThat(result.getStatus()).isSameAs(Result.Status.ERROR);
     assertThat(result.toString())
@@ -214,7 +216,7 @@ public class CreateMappingCommandTest {
     when(matchingRegion.getCustomRegionElements()).thenReturn(customList);
 
     ResultModel result = createRegionMappingCommand.createMapping(regionName, 
dataSourceName,
-        tableName, pdxClass, false);
+        tableName, pdxClass, false, null);
 
     assertThat(result.getStatus()).isSameAs(Result.Status.ERROR);
     assertThat(result.toString()).contains("A JDBC mapping for " + regionName 
+ " already exists.");
@@ -238,7 +240,7 @@ public class CreateMappingCommandTest {
     when(matchingRegion.getRegionAttributes()).thenReturn(loaderAttribute);
 
     ResultModel result = createRegionMappingCommand.createMapping(regionName, 
dataSourceName,
-        tableName, pdxClass, false);
+        tableName, pdxClass, false, null);
 
     assertThat(result.getStatus()).isSameAs(Result.Status.ERROR);
     assertThat(result.toString()).contains("The existing region " + regionName
@@ -263,7 +265,7 @@ public class CreateMappingCommandTest {
     when(matchingRegion.getRegionAttributes()).thenReturn(writerAttribute);
 
     ResultModel result = createRegionMappingCommand.createMapping(regionName, 
dataSourceName,
-        tableName, pdxClass, true);
+        tableName, pdxClass, true, null);
 
     assertThat(result.getStatus()).isSameAs(Result.Status.ERROR);
     assertThat(result.toString()).contains("The existing region " + regionName
@@ -292,7 +294,7 @@ public class CreateMappingCommandTest {
     when(cacheConfig.getAsyncEventQueues()).thenReturn(asyncEventQueues);
 
     ResultModel result = createRegionMappingCommand.createMapping(regionName, 
dataSourceName,
-        tableName, pdxClass, true);
+        tableName, pdxClass, true, null);
 
     assertThat(result.getStatus()).isSameAs(Result.Status.OK);
   }
@@ -320,7 +322,7 @@ public class CreateMappingCommandTest {
     when(cacheConfig.getAsyncEventQueues()).thenReturn(asyncEventQueues);
 
     ResultModel result = createRegionMappingCommand.createMapping(regionName, 
dataSourceName,
-        tableName, pdxClass, false);
+        tableName, pdxClass, false, null);
 
     assertThat(result.getStatus()).isSameAs(Result.Status.ERROR);
     assertThat(result.toString())
diff --git 
a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingFunctionTest.java
 
b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingFunctionTest.java
index 955b57f..f28a2fa 100644
--- 
a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingFunctionTest.java
+++ 
b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/CreateMappingFunctionTest.java
@@ -76,7 +76,7 @@ public class CreateMappingFunctionTest {
     distributedMember = mock(DistributedMember.class);
     service = mock(JdbcConnectorService.class);
 
-    regionMapping = new RegionMapping(REGION_NAME, null, null, null);
+    regionMapping = new RegionMapping(REGION_NAME, null, null, null, null);
 
     when(context.getResultSender()).thenReturn(resultSender);
     when(context.getCache()).thenReturn(cache);
diff --git 
a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeMappingCommandTest.java
 
b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeMappingCommandTest.java
index d317982..674b1ae 100644
--- 
a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeMappingCommandTest.java
+++ 
b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/DescribeMappingCommandTest.java
@@ -69,16 +69,19 @@ public class DescribeMappingCommandTest {
         null);
 
     RegionMapping mapping =
-        new RegionMapping("region", "class1", "table1", "name1");
+        new RegionMapping("region", "class1", "table1", "name1", "myId");
 
     ResultCollector rc = mock(ResultCollector.class);
     doReturn(rc).when(command).executeFunction(any(), any(), any(Set.class));
     when(rc.getResult()).thenReturn(
         Collections.singletonList(new CliFunctionResult("server-1", mapping, 
"success")));
 
-    gfsh.executeAndAssertThat(command, 
COMMAND).statusIsSuccess().containsOutput("region", "region")
-        .containsOutput("data-source", "name1").containsOutput("table", 
"table1")
-        .containsOutput("pdx-name", "class1");
+    gfsh.executeAndAssertThat(command, COMMAND).statusIsSuccess()
+        .containsOutput("region", "region")
+        .containsOutput("data-source", "name1")
+        .containsOutput("table", "table1")
+        .containsOutput("pdx-name", "class1")
+        .containsOutput("id", "myId");
   }
 
   @Test
diff --git 
a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/ListMappingCommandTest.java
 
b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/ListMappingCommandTest.java
index 1ae457e..6a2c719 100644
--- 
a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/ListMappingCommandTest.java
+++ 
b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/cli/ListMappingCommandTest.java
@@ -62,9 +62,9 @@ public class ListMappingCommandTest {
         null);
 
     RegionMapping mapping1 =
-        new RegionMapping("region1", "class1", "table1", "name1");
+        new RegionMapping("region1", "class1", "table1", "name1", null);
     RegionMapping mapping2 =
-        new RegionMapping("region2", "class2", "table2", "name2");
+        new RegionMapping("region2", "class2", "table2", "name2", null);
 
     ResultCollector rc = mock(ResultCollector.class);
     doReturn(rc).when(command).executeFunction(any(), any(), any(Set.class));
diff --git 
a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/xml/ElementTypeTest.java
 
b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/xml/ElementTypeTest.java
index 295a27b..9b15900 100644
--- 
a/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/xml/ElementTypeTest.java
+++ 
b/geode-connectors/src/test/java/org/apache/geode/connectors/jdbc/internal/xml/ElementTypeTest.java
@@ -17,6 +17,7 @@ package org.apache.geode.connectors.jdbc.internal.xml;
 
 import static 
org.apache.geode.connectors.jdbc.internal.xml.ElementType.JDBC_MAPPING;
 import static 
org.apache.geode.connectors.jdbc.internal.xml.JdbcConnectorServiceXmlParser.DATA_SOURCE;
+import static 
org.apache.geode.connectors.jdbc.internal.xml.JdbcConnectorServiceXmlParser.IDS;
 import static 
org.apache.geode.connectors.jdbc.internal.xml.JdbcConnectorServiceXmlParser.PDX_NAME;
 import static 
org.apache.geode.connectors.jdbc.internal.xml.JdbcConnectorServiceXmlParser.TABLE;
 import static org.assertj.core.api.Assertions.assertThat;
@@ -73,6 +74,7 @@ public class ElementTypeTest {
     when(attributes.getValue(DATA_SOURCE)).thenReturn("connectionName");
     when(attributes.getValue(TABLE)).thenReturn("table");
     when(attributes.getValue(PDX_NAME)).thenReturn("pdxClass");
+    when(attributes.getValue(IDS)).thenReturn("ids");
     when(regionCreation.getFullPath()).thenReturn("/region");
     stack.push(regionCreation);
 
@@ -83,6 +85,7 @@ public class ElementTypeTest {
     assertThat(regionMapping.getDataSourceName()).isEqualTo("connectionName");
     assertThat(regionMapping.getTableName()).isEqualTo("table");
     assertThat(regionMapping.getPdxName()).isEqualTo("pdxClass");
+    assertThat(regionMapping.getIds()).isEqualTo("ids");
   }
 
   @Test

Reply via email to