This is an automated email from the ASF dual-hosted git repository.
dengzh pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/hive.git
The following commit(s) were added to refs/heads/master by this push:
new 0022d49cb17 HIVE-29316: Concurrency issue in
updatePartitionColumnStatistics (#6188)
0022d49cb17 is described below
commit 0022d49cb17b9cbd769271ffd13d243f252ddf59
Author: dengzh <[email protected]>
AuthorDate: Fri Nov 21 15:27:44 2025 +0800
HIVE-29316: Concurrency issue in updatePartitionColumnStatistics (#6188)
---
.../clientpositive/llap/show_partitions2.q.out | 2 +-
.../hadoop/hive/metastore/conf/MetastoreConf.java | 4 +-
.../apache/hadoop/hive/metastore/ObjectStore.java | 159 ++++++++++++---------
.../org/apache/hadoop/hive/metastore/RawStore.java | 2 +
.../hadoop/hive/metastore/model/MPartition.java | 7 +-
.../hive/metastore/utils/RetryingExecutor.java | 28 ++--
.../src/main/resources/package.jdo | 8 +-
7 files changed, 119 insertions(+), 91 deletions(-)
diff --git a/ql/src/test/results/clientpositive/llap/show_partitions2.q.out
b/ql/src/test/results/clientpositive/llap/show_partitions2.q.out
index 1ed9eaa56b7..3b6184a6164 100644
--- a/ql/src/test/results/clientpositive/llap/show_partitions2.q.out
+++ b/ql/src/test/results/clientpositive/llap/show_partitions2.q.out
@@ -211,8 +211,8 @@ PREHOOK: Input: default@mpart1
POSTHOOK: query: SHOW PARTITIONS mpart1 PARTITION(ds = '1980-11-10') LIMIT 3
POSTHOOK: type: SHOWPARTITIONS
POSTHOOK: Input: default@mpart1
-ds=1980-11-10/hr=12/rs=EU
ds=1980-11-10/hr=10/rs=AS
+ds=1980-11-10/hr=12/rs=EU
ds=1980-11-10/hr=15/rs=EU
PREHOOK: query: SHOW PARTITIONS mpart1 where ds = '__HIVE_DEFAULT_PARTITION__'
AND hr = '__HIVE_DEFAULT_PARTITION__'
PREHOOK: type: SHOWPARTITIONS
diff --git
a/standalone-metastore/metastore-common/src/main/java/org/apache/hadoop/hive/metastore/conf/MetastoreConf.java
b/standalone-metastore/metastore-common/src/main/java/org/apache/hadoop/hive/metastore/conf/MetastoreConf.java
index 0b6fd083123..85b37d67889 100644
---
a/standalone-metastore/metastore-common/src/main/java/org/apache/hadoop/hive/metastore/conf/MetastoreConf.java
+++
b/standalone-metastore/metastore-common/src/main/java/org/apache/hadoop/hive/metastore/conf/MetastoreConf.java
@@ -270,7 +270,9 @@ public String toString() {
ConfVars.PARTITION_ORDER_EXPR,
ConfVars.CAPABILITY_CHECK,
ConfVars.DISALLOW_INCOMPATIBLE_COL_TYPE_CHANGES,
- ConfVars.EXPRESSION_PROXY_CLASS
+ ConfVars.EXPRESSION_PROXY_CLASS,
+ ConfVars.METASTORE_S4U_NOWAIT_MAX_RETRIES,
+ ConfVars.METASTORE_S4U_NOWAIT_RETRY_SLEEP_INTERVAL
};
static {
diff --git
a/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/ObjectStore.java
b/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/ObjectStore.java
index 659f47e7035..53c4793d029 100644
---
a/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/ObjectStore.java
+++
b/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/ObjectStore.java
@@ -27,6 +27,7 @@
import java.io.IOException;
import java.net.InetAddress;
import java.sql.Connection;
+import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.SQLIntegrityConstraintViolationException;
import java.sql.Statement;
@@ -3608,7 +3609,7 @@ protected Integer getJdoResult(GetHelper<Integer> ctx)
* you want results for. E.g., if resultsCol is partitionName, the
Collection
* has types of String, and if resultsCol is null, the types are
MPartition.
*/
- private Collection<String> getPartitionPsQueryResults(String catName, String
dbName,
+ private <T> Collection<T> getPartitionPsQueryResults(String catName, String
dbName,
String tableName,
List<String> part_vals,
int max_parts, String
resultsCol)
throws MetaException, NoSuchObjectException {
@@ -3628,6 +3629,7 @@ private Collection<String>
getPartitionPsQueryResults(String catName, String dbN
String filter = getJDOFilterStrForPartitionVals(table, part_vals, params);
try (QueryWrapper query = new QueryWrapper(pm.newQuery(MPartition.class)))
{
query.setFilter(filter);
+ query.setOrdering("partitionName ascending");
query.declareParameters(makeParameterDeclarationString(params));
if (max_parts >= 0) {
// User specified a row limit, set it on the Query
@@ -3637,7 +3639,7 @@ private Collection<String>
getPartitionPsQueryResults(String catName, String dbN
query.setResult(resultsCol);
}
- Collection<String> result = (Collection<String>)
query.executeWithMap(params);
+ Collection<T> result = (Collection<T>) query.executeWithMap(params);
return Collections.unmodifiableCollection(new ArrayList<>(result));
}
@@ -3709,11 +3711,11 @@ protected List<Partition>
getSqlResult(GetHelper<List<Partition>> ctx) throws Me
protected List<Partition> getJdoResult(GetHelper<List<Partition>> ctx)
throws MetaException, NoSuchObjectException {
List<Partition> result = new ArrayList<>();
- Collection parts = getPartitionPsQueryResults(catName, dbName, tblName,
+ Collection<MPartition> parts = getPartitionPsQueryResults(catName,
dbName, tblName,
args.getPart_vals(), args.getMax(), null);
boolean isAcidTable = TxnUtils.isAcidTable(ctx.getTable());
- for (Object o : parts) {
- Partition part = convertToPart(catName, dbName, tblName,
(MPartition) o, isAcidTable, args);
+ for (MPartition o : parts) {
+ Partition part = convertToPart(catName, dbName, tblName, o,
isAcidTable, args);
result.add(part);
}
return result;
@@ -9177,6 +9179,7 @@ public Map<String, String>
updateTableColumnStatistics(ColumnStatistics colStats
setTransactionSavePoint(savePoint);
executePlainSQL(
sqlGenerator.addForUpdateNoWait("SELECT \"TBL_ID\" FROM \"TBLS\"
WHERE \"TBL_ID\" = " + mTable.getId()),
+ true,
exception -> {
rollbackTransactionToSavePoint(savePoint);
exceptionRef.t = exception;
@@ -9204,7 +9207,6 @@ public Map<String, String>
updateTableColumnStatistics(ColumnStatistics colStats
// There is no need to add colname again, otherwise we will get
duplicate colNames.
}
- // TODO: (HIVE-20109) ideally the col stats stats should be in
colstats, not in the table!
// Set the table properties
// No need to check again if it exists.
String dbname = table.getDbName();
@@ -9236,7 +9238,6 @@ public Map<String, String>
updateTableColumnStatistics(ColumnStatistics colStats
.commandName("updateTableColumnStatistics").sleepInterval(sleepInterval,
interval ->
ThreadLocalRandom.current().nextLong(sleepInterval) + 30).run();
committed = commitTransaction();
- // TODO: similar to update...Part, this used to do "return committed;";
makes little sense.
return committed ? result : null;
} finally {
LOG.debug("{} updateTableColumnStatistics took {}ms, success: {}",
@@ -9246,85 +9247,93 @@ public Map<String, String>
updateTableColumnStatistics(ColumnStatistics colStats
}
}
- /**
- * Get partition's column stats
- *
- * @return Map of column name and its stats
- */
- private Map<String, MPartitionColumnStatistics> getPartitionColStats(Table
table, String partitionName,
- List<String> colNames, String engine) throws NoSuchObjectException,
MetaException {
- Map<String, MPartitionColumnStatistics> statsMap = Maps.newHashMap();
- List<MPartitionColumnStatistics> stats =
- getMPartitionColumnStatistics(table,
Lists.newArrayList(partitionName), colNames, engine);
- for (MPartitionColumnStatistics cStat : stats) {
- statsMap.put(cStat.getColName(), cStat);
- }
- return statsMap;
- }
-
@Override
public Map<String, String> updatePartitionColumnStatistics(Table table,
MTable mTable, ColumnStatistics colStats,
List<String> partVals, String validWriteIds, long writeId)
throws MetaException, NoSuchObjectException, InvalidObjectException,
InvalidInputException {
boolean committed = false;
-
+ long start = System.currentTimeMillis();
+ List<ColumnStatisticsObj> statsObjs = colStats.getStatsObj();
+ ColumnStatisticsDesc statsDesc = colStats.getStatsDesc();
+ String catName = statsDesc.isSetCatName() ? statsDesc.getCatName() :
getDefaultCatalog(conf);
try {
openTransaction();
- List<ColumnStatisticsObj> statsObjs = colStats.getStatsObj();
- ColumnStatisticsDesc statsDesc = colStats.getStatsDesc();
- String catName = statsDesc.isSetCatName() ? statsDesc.getCatName() :
getDefaultCatalog(conf);
- Partition partition = convertToPart(catName, statsDesc.getDbName(),
statsDesc.getTableName(), getMPartition(
- catName, statsDesc.getDbName(), statsDesc.getTableName(), partVals,
mTable), TxnUtils.isAcidTable(table));
- List<String> colNames = new ArrayList<>();
-
- for(ColumnStatisticsObj statsObj : statsObjs) {
- colNames.add(statsObj.getColName());
- }
-
- Map<String, MPartitionColumnStatistics> oldStats =
getPartitionColStats(table, statsDesc
- .getPartName(), colNames, colStats.getEngine());
-
MPartition mPartition = getMPartition(
catName, statsDesc.getDbName(), statsDesc.getTableName(), partVals,
mTable);
- if (partition == null) {
+ if (mPartition == null) {
throw new NoSuchObjectException("Partition for which stats is gathered
doesn't exist.");
}
- for (ColumnStatisticsObj statsObj : statsObjs) {
- MPartitionColumnStatistics mStatsObj =
-
StatObjectConverter.convertToMPartitionColumnStatistics(mPartition, statsDesc,
statsObj, colStats.getEngine());
- writeMPartitionColumnStatistics(table, partition, mStatsObj,
- oldStats.get(statsObj.getColName()));
+ List<String> colNames = new ArrayList<>();
+ for(ColumnStatisticsObj statsObj : statsObjs) {
+ colNames.add(statsObj.getColName());
}
- // TODO: (HIVE-20109) the col stats stats should be in colstats, not in
the partition!
- Map<String, String> newParams = new
HashMap<>(mPartition.getParameters());
- StatsSetupConst.setColumnStatsState(newParams, colNames);
- boolean isTxn = TxnUtils.isTransactionalTable(table);
- if (isTxn) {
- if (!areTxnStatsSupported) {
- StatsSetupConst.setBasicStatsState(newParams, StatsSetupConst.FALSE);
- } else {
- String errorMsg =
verifyStatsChangeCtx(TableName.getDbTable(statsDesc.getDbName(),
-
statsDesc.getTableName()),
- mPartition.getParameters(), newParams, writeId,
validWriteIds, true);
- if (errorMsg != null) {
- throw new MetaException(errorMsg);
- }
- if (!isCurrentStatsValidForTheQuery(mPartition, validWriteIds,
true)) {
- // Make sure we set the flag to invalid regardless of the current
value.
+ int maxRetries = MetastoreConf.getIntVar(conf,
ConfVars.METASTORE_S4U_NOWAIT_MAX_RETRIES);
+ long sleepInterval = MetastoreConf.getTimeVar(conf,
+ ConfVars.METASTORE_S4U_NOWAIT_RETRY_SLEEP_INTERVAL,
TimeUnit.MILLISECONDS);
+ Map<String, String> result = new RetryingExecutor<>(maxRetries, () -> {
+ Ref<Exception> exceptionRef = new Ref<>();
+ String savePoint = "ups_" + ThreadLocalRandom.current().nextInt(10000)
+ "_" + System.nanoTime();
+ setTransactionSavePoint(savePoint);
+ executePlainSQL(sqlGenerator.addForUpdateNoWait(
+ "SELECT \"PART_ID\" FROM \"PARTITIONS\" WHERE \"PART_ID\" = " +
mPartition.getId()),
+ true,
+ exception -> {
+ rollbackTransactionToSavePoint(savePoint);
+ exceptionRef.t = exception;
+ });
+ if (exceptionRef.t != null) {
+ throw new RetryingExecutor.RetryException(exceptionRef.t);
+ }
+ pm.refresh(mPartition);
+ Partition partition = convertToPart(catName, statsDesc.getDbName(),
statsDesc.getTableName(),
+ mPartition, TxnUtils.isAcidTable(table));
+ Map<String, MPartitionColumnStatistics> oldStats = Maps.newHashMap();
+ List<MPartitionColumnStatistics> stats =
+ getMPartitionColumnStatistics(table,
Lists.newArrayList(statsDesc.getPartName()), colNames, colStats.getEngine());
+ for (MPartitionColumnStatistics cStat : stats) {
+ oldStats.put(cStat.getColName(), cStat);
+ }
+
+ for (ColumnStatisticsObj statsObj : statsObjs) {
+ MPartitionColumnStatistics mStatsObj =
StatObjectConverter.convertToMPartitionColumnStatistics(mPartition,
+ statsDesc, statsObj, colStats.getEngine());
+ writeMPartitionColumnStatistics(table, partition, mStatsObj,
oldStats.get(statsObj.getColName()));
+ }
+
+ Map<String, String> newParams = new
HashMap<>(mPartition.getParameters());
+ StatsSetupConst.setColumnStatsState(newParams, colNames);
+ boolean isTxn = TxnUtils.isTransactionalTable(table);
+ if (isTxn) {
+ if (!areTxnStatsSupported) {
StatsSetupConst.setBasicStatsState(newParams,
StatsSetupConst.FALSE);
- LOG.info("Removed COLUMN_STATS_ACCURATE from the parameters of the
partition "
- + statsDesc.getDbName() + "." + statsDesc.getTableName() +
"." + statsDesc.getPartName());
+ } else {
+ String errorMsg = verifyStatsChangeCtx(
+ TableName.getDbTable(statsDesc.getDbName(),
statsDesc.getTableName()), mPartition.getParameters(),
+ newParams, writeId, validWriteIds, true);
+ if (errorMsg != null) {
+ throw new MetaException(errorMsg);
+ }
+ if (!isCurrentStatsValidForTheQuery(mPartition, validWriteIds,
true)) {
+ // Make sure we set the flag to invalid regardless of the
current value.
+ StatsSetupConst.setBasicStatsState(newParams,
StatsSetupConst.FALSE);
+ LOG.info("Removed COLUMN_STATS_ACCURATE from the parameters of
the partition: {}, {} ",
+ new TableName(catName, statsDesc.getDbName(),
statsDesc.getTableName()), statsDesc.getPartName());
+ }
+ mPartition.setWriteId(writeId);
}
- mPartition.setWriteId(writeId);
}
- }
-
- mPartition.setParameters(newParams);
+ mPartition.setParameters(newParams);
+ return newParams;
+ }).onRetry(e -> e instanceof RetryingExecutor.RetryException)
+
.commandName("updatePartitionColumnStatistics").sleepInterval(sleepInterval,
interval ->
+ ThreadLocalRandom.current().nextLong(sleepInterval) + 30).run();
committed = commitTransaction();
- // TODO: what is the "return committed;" about? would it ever return
false without throwing?
- return committed ? newParams : null;
+ return committed ? result : null;
} finally {
+ LOG.debug("{} updatePartitionColumnStatistics took {}ms, success: {}",
+ new TableName(catName, statsDesc.getDbName(),
statsDesc.getTableName()),
+ System.currentTimeMillis() - start, committed);
rollbackAndCleanup(committed, null);
}
}
@@ -11080,8 +11089,10 @@ public List<WriteEventInfo> getAllWriteEventInfo(long
txnId, String dbName, Stri
return writeEventInfoList;
}
- private void executePlainSQL(String sql, Consumer<Exception>
exceptionConsumer)
- throws SQLException {
+ private void executePlainSQL(String sql,
+ boolean atLeastOneRecord,
+ Consumer<Exception> exceptionConsumer)
+ throws SQLException, MetaException {
String s = dbType.getPrepareTxnStmt();
assert pm.currentTransaction().isActive();
JDOConnection jdoConn = pm.getDataStoreConnection();
@@ -11092,6 +11103,12 @@ private void executePlainSQL(String sql,
Consumer<Exception> exceptionConsumer)
}
try {
statement.execute(sql);
+ try (ResultSet rs = statement.getResultSet()) {
+ // sqlserver needs rs.next for validating the s4u nowait
+ if (atLeastOneRecord && !rs.next()) {
+ throw new MetaException("At least one record but none is returned
from the query: " + sql);
+ }
+ }
} catch (SQLException e) {
if (exceptionConsumer != null) {
exceptionConsumer.accept(e);
@@ -11121,7 +11138,7 @@ private void lockNotificationSequenceForUpdate() throws
MetaException {
String selectQuery = "select \"NEXT_EVENT_ID\" from
\"NOTIFICATION_SEQUENCE\"";
String lockingQuery = sqlGenerator.addForUpdateClause(selectQuery);
new RetryingExecutor<Void>(maxRetries, () -> {
- executePlainSQL(lockingQuery, null);
+ executePlainSQL(lockingQuery, false, null);
return null;
}).commandName("lockNotificationSequenceForUpdate").sleepInterval(sleepInterval).run();
}
diff --git
a/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/RawStore.java
b/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/RawStore.java
index f4db86722f0..266972db85a 100644
---
a/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/RawStore.java
+++
b/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/RawStore.java
@@ -1094,6 +1094,7 @@ Map<String, String>
updateTableColumnStatistics(ColumnStatistics colStats, Strin
throws NoSuchObjectException, MetaException, InvalidObjectException,
InvalidInputException;
/** Persists the given column statistics object to the metastore
+ * @deprecated Use {@link #updatePartitionColumnStatistics(Table, MTable,
ColumnStatistics, List, String, long)} instead
* @param statsObj object to persist
* @param partVals partition values to persist the stats for
* @return Boolean indicating the outcome of the operation
@@ -1102,6 +1103,7 @@ Map<String, String>
updateTableColumnStatistics(ColumnStatistics colStats, Strin
* @throws InvalidObjectException the stats object is invalid
* @throws InvalidInputException unable to record the stats for the table
*/
+ @Deprecated
Map<String, String> updatePartitionColumnStatistics(ColumnStatistics
statsObj,
List<String> partVals, String validWriteIds, long writeId)
throws NoSuchObjectException, MetaException, InvalidObjectException,
InvalidInputException;
diff --git
a/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/model/MPartition.java
b/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/model/MPartition.java
index 267c9e8e5ac..f4750649505 100644
---
a/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/model/MPartition.java
+++
b/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/model/MPartition.java
@@ -22,7 +22,7 @@
import java.util.Map;
public class MPartition {
-
+ private long id;
private String partitionName; // partitionname ==> (key=value/)*(key=value)
private MTable table;
private List<String> values;
@@ -31,7 +31,6 @@ public class MPartition {
private MStorageDescriptor sd;
private Map<String, String> parameters;
private long writeId;
-
public MPartition() {}
/**
@@ -159,4 +158,8 @@ public long getWriteId() {
public void setWriteId(long writeId) {
this.writeId = writeId;
}
+
+ public long getId() {
+ return id;
+ }
}
diff --git
a/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/utils/RetryingExecutor.java
b/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/utils/RetryingExecutor.java
index dcaa10be831..74c9a44f6ef 100644
---
a/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/utils/RetryingExecutor.java
+++
b/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/utils/RetryingExecutor.java
@@ -35,7 +35,7 @@ public class RetryingExecutor<T> {
private final int maxRetries;
private long sleepInterval = 1000;
private final Callable<T> command;
- private Predicate<Exception> retryPolicy;
+ private Predicate<Throwable> retryPolicy;
private int currentRetries = 0;
private String commandName;
private Function<Long, Long> sleepIntervalFunc;
@@ -51,7 +51,7 @@ public RetryingExecutor(int maxRetries, Callable<T> command) {
.map(StackWalker.StackFrame::getMethodName)).get();
}
- public RetryingExecutor<T> onRetry(Predicate<Exception> retryPolicy) {
+ public RetryingExecutor<T> onRetry(Predicate<Throwable> retryPolicy) {
this.retryPolicy = retryPolicy;
return this;
}
@@ -77,9 +77,9 @@ public T run() throws MetaException {
try {
return command.call();
} catch (Exception e) {
- checkException(e);
- LOG.info("Attempting to retry the command:{} in {} out of {} retries",
- commandName, currentRetries, maxRetries, e);
+ Throwable t = checkException(e);
+ LOG.info("Attempting to retry the command:{} in {} out of {} retries,
error message: {}",
+ commandName, currentRetries, maxRetries, t.getMessage());
if (currentRetries >= maxRetries) {
String message = "Couldn't finish the command: " + commandName +
" because we reached the maximum of retries: " + maxRetries;
@@ -95,22 +95,26 @@ public T run() throws MetaException {
LOG.error(msg, e1);
throw new MetaException(msg + e1.getMessage());
}
+ LOG.debug("Exception occurred in running: {}", commandName, t);
}
}
}
- private void checkException(Exception e) throws MetaException {
- if (retryPolicy != null && !retryPolicy.test(e)) {
+ private Throwable checkException(Throwable e) throws MetaException {
+ Throwable cause = e;
+ if (e instanceof InvocationTargetException ||
+ e instanceof UndeclaredThrowableException) {
+ cause = e.getCause();
+ }
+ if (retryPolicy != null && !retryPolicy.test(cause)) {
String message = "See a fatal exception, avoid to retry the command:" +
commandName;
- LOG.info(message, e);
- String errorMessage = ExceptionUtils.getMessage(e);
- if (e instanceof InvocationTargetException || e instanceof
UndeclaredThrowableException) {
- errorMessage = ExceptionUtils.getMessage(e.getCause());
- }
+ LOG.error(message, cause);
+ String errorMessage = ExceptionUtils.getMessage(cause);
Throwable rootCause = ExceptionUtils.getRootCause(e);
errorMessage += (rootCause == null ? "" : ("\nRoot cause: " +
rootCause));
throw new MetaException(message + " :: " + errorMessage);
}
+ return cause;
}
public static class RetryException extends Exception {
diff --git
a/standalone-metastore/metastore-server/src/main/resources/package.jdo
b/standalone-metastore/metastore-server/src/main/resources/package.jdo
index af5209ff07e..8e29e0a3522 100644
--- a/standalone-metastore/metastore-server/src/main/resources/package.jdo
+++ b/standalone-metastore/metastore-server/src/main/resources/package.jdo
@@ -506,15 +506,15 @@
</field>
</class>
- <class name="MPartition" table="PARTITIONS" identity-type="datastore"
detachable="true">
+ <class name="MPartition" table="PARTITIONS" identity-type="application"
detachable="true">
<foreign-key name="PARTITIONS_FK1" delete-action="cascade"/>
<index name="UniquePartition" unique="true">
<column name="PART_NAME"/>
<column name="TBL_ID"/>
</index>
- <datastore-identity>
- <column name="PART_ID"/>
- </datastore-identity>
+ <field name="id" primary-key="true" value-strategy="native">
+ <column name="PART_ID" jdbc-type="BIGINT" />
+ </field>
<field name="partitionName">
<column name="PART_NAME" length="767" jdbc-type="VARCHAR"/>
</field>