This is an automated email from the ASF dual-hosted git repository.
isapego pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/ignite-3.git
The following commit(s) were added to refs/heads/main by this push:
new 02e70008bae IGNITE-28426 Migration Tools: Fix SqlDdlGenerator nested
POJOs bug (#7912)
02e70008bae is described below
commit 02e70008baea8a0273c12efe44f36e326b7f4983
Author: Tiago Marques Godinho <[email protected]>
AuthorDate: Mon Apr 13 13:48:22 2026 +0100
IGNITE-28426 Migration Tools: Fix SqlDdlGenerator nested POJOs bug (#7912)
---
.../tests/models/NestedPojoWithAnnotations.java | 61 ++++++++++++++++++++++
.../ignite/migrationtools/sql/SqlDdlGenerator.java | 31 ++++++++++-
.../ignite/migrationtools/types/TypeInspector.java | 8 ++-
.../sql/sql/SqlDdlGeneratorTest.java | 23 ++++++++
4 files changed, 120 insertions(+), 3 deletions(-)
diff --git
a/migration-tools/modules/migration-tools-commons-tests/src/main/java/org/apache/ignite/migrationtools/tests/models/NestedPojoWithAnnotations.java
b/migration-tools/modules/migration-tools-commons-tests/src/main/java/org/apache/ignite/migrationtools/tests/models/NestedPojoWithAnnotations.java
new file mode 100644
index 00000000000..beb074b2d17
--- /dev/null
+++
b/migration-tools/modules/migration-tools-commons-tests/src/main/java/org/apache/ignite/migrationtools/tests/models/NestedPojoWithAnnotations.java
@@ -0,0 +1,61 @@
+/*
+ * 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.migrationtools.tests.models;
+
+import java.util.Objects;
+import org.apache.ignite.cache.query.annotations.QuerySqlField;
+
+/** NestedPojoWithAnnotations. */
+public class NestedPojoWithAnnotations {
+ @QuerySqlField
+ private long id;
+
+ @QuerySqlField
+ private SimplePojo nestedPojo;
+
+ public NestedPojoWithAnnotations() {
+ // Intentionally left blank.
+ }
+
+ public NestedPojoWithAnnotations(long id, SimplePojo nestedObj) {
+ this.id = id;
+ this.nestedPojo = nestedObj;
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public SimplePojo getNestedPojo() {
+ return nestedPojo;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof NestedPojoWithAnnotations)) {
+ return false;
+ }
+ NestedPojoWithAnnotations that = (NestedPojoWithAnnotations) o;
+ return id == that.id && Objects.equals(nestedPojo, that.nestedPojo);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(id, nestedPojo);
+ }
+}
diff --git
a/migration-tools/modules/migration-tools-commons/src/main/java/org/apache/ignite/migrationtools/sql/SqlDdlGenerator.java
b/migration-tools/modules/migration-tools-commons/src/main/java/org/apache/ignite/migrationtools/sql/SqlDdlGenerator.java
index 821b0d57b5b..d942d8911f1 100644
---
a/migration-tools/modules/migration-tools-commons/src/main/java/org/apache/ignite/migrationtools/sql/SqlDdlGenerator.java
+++
b/migration-tools/modules/migration-tools-commons/src/main/java/org/apache/ignite/migrationtools/sql/SqlDdlGenerator.java
@@ -26,6 +26,7 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Map.Entry;
import java.util.Optional;
import java.util.Set;
import java.util.function.Function;
@@ -388,6 +389,9 @@ public class SqlDdlGenerator {
}
}
+ // Tracks whether this QE maps a POJO on either Key/Value.
+ boolean mapsPojo = false;
+
// Go over existing fields in the QE to they are correct and there are
not silly nulls.
{
// AI2 may define primitive field types, however, they still mark
them as nullable somehow.
@@ -430,6 +434,29 @@ public class SqlDdlGenerator {
// Mark keyFields as not nullable.
qe.getNotNullFields().addAll(qe.getKeyFields());
+
+ // We also want to remove fields non-compliant with AI3 so that
they are handled in the extra fields.
+ for (Iterator<Entry<String, String>> it =
qe.getFields().entrySet().iterator(); it.hasNext(); ) {
+ Entry<String, String> e = it.next();
+ String fieldType = ClassnameUtils.ensureWrapper(e.getValue());
+
+ boolean isNativelySupportedType;
+ try {
+ Class<?> type =
ClassUtils.getClass(this.clientClassLoader, fieldType);
+ isNativelySupportedType =
TypeInspector.isPrimitiveType(type);
+ } catch (ClassNotFoundException ignored) {
+ // All natively supported types should be in the classpath.
+ // Some enums might still slip through.
+ isNativelySupportedType = false;
+ }
+
+ // Remove from the field list, we will need to map it in the
extra fields.
+ if (!isNativelySupportedType) {
+ mapsPojo = true;
+ it.remove();
+ qe.getKeyFields().remove(e.getKey());
+ }
+ }
}
@Nullable Map<InspectedField, String> keyFieldToColumnMap;
@@ -558,7 +585,7 @@ public class SqlDdlGenerator {
}
// Empty field lists means that the class for the type is not
available on the classpath so it must be a pojo.
- boolean mapsPojo = keyFields.isEmpty() || valFields.isEmpty();
+ mapsPojo = mapsPojo || keyFields.isEmpty() || valFields.isEmpty();
// Process key fields
{
@@ -583,7 +610,7 @@ public class SqlDdlGenerator {
// Process value fields
{
- if (valFields.size() == 1) {
+ if (valFields.size() == 1 && !mapsPojo) {
InspectedField inspectedField = valFields.get(0);
String columnName = valFieldToColumnMap.get(inspectedField);
diff --git
a/migration-tools/modules/migration-tools-commons/src/main/java/org/apache/ignite/migrationtools/types/TypeInspector.java
b/migration-tools/modules/migration-tools-commons/src/main/java/org/apache/ignite/migrationtools/types/TypeInspector.java
index 9dc4630c5a8..66e381c1411 100644
---
a/migration-tools/modules/migration-tools-commons/src/main/java/org/apache/ignite/migrationtools/types/TypeInspector.java
+++
b/migration-tools/modules/migration-tools-commons/src/main/java/org/apache/ignite/migrationtools/types/TypeInspector.java
@@ -133,7 +133,13 @@ public class TypeInspector {
}
}
- private static boolean isPrimitiveType(Class<?> type) {
+ /**
+ * Whether the provided class, or its derivatives, is natively supported.
+ *
+ * @param type Type.
+ * @return True or false.
+ */
+ public static boolean isPrimitiveType(Class<?> type) {
return type.isEnum() || Mapper.nativelySupported(type) ||
COL_TYPE_REF.containsKey(type);
}
diff --git
a/migration-tools/modules/migration-tools-commons/src/test/java/org/apache/ignite/migrationtools/sql/sql/SqlDdlGeneratorTest.java
b/migration-tools/modules/migration-tools-commons/src/test/java/org/apache/ignite/migrationtools/sql/sql/SqlDdlGeneratorTest.java
index 588fbbaef6e..440c250baa5 100644
---
a/migration-tools/modules/migration-tools-commons/src/test/java/org/apache/ignite/migrationtools/sql/sql/SqlDdlGeneratorTest.java
+++
b/migration-tools/modules/migration-tools-commons/src/test/java/org/apache/ignite/migrationtools/sql/sql/SqlDdlGeneratorTest.java
@@ -64,6 +64,7 @@ import
org.apache.ignite.migrationtools.tablemanagement.TableTypeRegistryMapImpl
import org.apache.ignite.migrationtools.tests.models.ComplexKeyIntStr;
import org.apache.ignite.migrationtools.tests.models.IdentifiedPojo;
import org.apache.ignite.migrationtools.tests.models.InterceptingFieldsModel;
+import org.apache.ignite.migrationtools.tests.models.NestedPojoWithAnnotations;
import org.apache.ignite.migrationtools.tests.models.SimplePojo;
import org.apache.ignite3.catalog.ColumnSorted;
import org.apache.ignite3.catalog.definitions.ColumnDefinition;
@@ -347,6 +348,28 @@ class SqlDdlGeneratorTest {
);
}
+ @ParameterizedTest
+ @MethodSource("provideCacheConfigSupplier")
+ void testTableDefWithNestedPojoWithAnnotations(
+ BiFunction<Class<?>, Class<?>, CacheConfiguration<?, ?>>
cacheConfigSupplier,
+ boolean allowExtraFields
+ ) {
+ var cacheCfg = cacheConfigSupplier.apply(String.class,
NestedPojoWithAnnotations.class);
+ testCacheConfig(
+ cacheCfg,
+ allowExtraFields,
+ List.of(
+ primaryKey("KEY", "VARCHAR"),
+ nonKey("id", "BIGINT", false)
+ ),
+ entry(String.class.getName(),
NestedPojoWithAnnotations.class.getName()),
+ emptyMap(),
+ Map.ofEntries(
+ entry("id", "id")
+ )
+ );
+ }
+
@ParameterizedTest
@MethodSource("provideCacheConfigSupplier")
void testTableDefWithOrganizationPojo(