This is an automated email from the ASF dual-hosted git repository.
wernerdv pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite.git
The following commit(s) were added to refs/heads/master by this push:
new 88d7dfb824f IGNITE-28930 Default field values are lost on remote nodes
when a query entity is added dynamically (#13430)
88d7dfb824f is described below
commit 88d7dfb824f1e1ce8a23d42bd314e71c37a4e1ed
Author: Dmitry Werner <[email protected]>
AuthorDate: Wed Aug 5 21:17:55 2026 +0500
IGNITE-28930 Default field values are lost on remote nodes when a query
entity is added dynamically (#13430)
---
.../internal/processors/cache/CacheData.java | 2 +-
.../query/schema/message/QueryEntityMessage.java | 2 +-
.../operation/SchemaAddQueryEntityOperation.java | 2 +-
.../QueryEntityMessageSerializationTest.java | 59 +++++++++++++++++-----
4 files changed, 50 insertions(+), 15 deletions(-)
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheData.java
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheData.java
index b41be15bbe8..833f736295c 100644
---
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheData.java
+++
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheData.java
@@ -113,7 +113,7 @@ public class CacheData implements Message {
this.grpId = grpId;
this.cacheType = cacheType;
this.deploymentId = deploymentId;
- entitiesMsgs = F.viewReadOnly(schema.entities(),
QueryEntityMessage::new);
+ entitiesMsgs = F.transform(schema.entities(), QueryEntityMessage::new);
this.rcvdFrom = rcvdFrom;
this.staticCfg = staticCfg;
this.sql = sql;
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/schema/message/QueryEntityMessage.java
b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/schema/message/QueryEntityMessage.java
index 27ad8c0eb5a..f1c2b245f9c 100644
---
a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/schema/message/QueryEntityMessage.java
+++
b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/schema/message/QueryEntityMessage.java
@@ -112,7 +112,7 @@ public class QueryEntityMessage implements Message {
keyFields = qryEntity.getKeyFields().toArray(U.EMPTY_STRS);
if (!F.isEmpty(qryEntity.getIndexes()))
- idxs = F.viewReadOnly(qryEntity.getIndexes(),
QueryIndexMessage::new);
+ idxs = F.transform(qryEntity.getIndexes(), QueryIndexMessage::new);
tableName = qryEntity.getTableName();
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/schema/operation/SchemaAddQueryEntityOperation.java
b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/schema/operation/SchemaAddQueryEntityOperation.java
index 3d700460bb7..69fd8874f8c 100644
---
a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/schema/operation/SchemaAddQueryEntityOperation.java
+++
b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/schema/operation/SchemaAddQueryEntityOperation.java
@@ -67,7 +67,7 @@ public class SchemaAddQueryEntityOperation extends
SchemaAbstractOperation {
this.qryParallelism = qryParallelism;
this.sqlEscape = sqlEscape;
- entitiesMsgs = F.viewReadOnly(entities, this::makeEntityMessage);
+ entitiesMsgs = F.transform(entities, this::makeEntityMessage);
}
/** @return Collection of query entities. */
diff --git
a/modules/core/src/test/java/org/apache/ignite/internal/processors/query/schema/message/QueryEntityMessageSerializationTest.java
b/modules/core/src/test/java/org/apache/ignite/internal/processors/query/schema/message/QueryEntityMessageSerializationTest.java
index 76b340a3eae..a639322a976 100644
---
a/modules/core/src/test/java/org/apache/ignite/internal/processors/query/schema/message/QueryEntityMessageSerializationTest.java
+++
b/modules/core/src/test/java/org/apache/ignite/internal/processors/query/schema/message/QueryEntityMessageSerializationTest.java
@@ -27,6 +27,7 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.UUID;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.cache.QueryEntity;
import org.apache.ignite.cache.QueryIndex;
@@ -37,6 +38,7 @@ import org.apache.ignite.internal.direct.DirectMessageWriter;
import
org.apache.ignite.internal.managers.communication.IgniteMessageFactoryImpl;
import org.apache.ignite.internal.managers.communication.MessageMarshalling;
import org.apache.ignite.internal.processors.query.QueryEntityEx;
+import
org.apache.ignite.internal.processors.query.schema.operation.SchemaAddQueryEntityOperation;
import org.apache.ignite.internal.util.nio.MessageSerialization;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.marshaller.Marshaller;
@@ -54,14 +56,27 @@ import static org.apache.ignite.marshaller.Marshallers.jdk;
/** Test for serialization round-trip of {@link QueryEntityMessage} and {@link
QueryEntityExMessage}. */
public class QueryEntityMessageSerializationTest extends
GridCommonAbstractTest {
/** Error suffix. */
- public static final String ERROR_SUFFIX = " count is not equal to the
expected fields count. " +
+ private static final String ERROR_SUFFIX = " count is not equal to the
expected fields count. " +
"Has the number of fields in the `QueryEntity` or `QueryEntityEx`
classes changed?";
+ /** */
+ private static final LinkedHashMap<String, String> FIELDS = new
LinkedHashMap<>(Map.of(
+ "id", Integer.class.getName(),
+ "name", String.class.getName(),
+ "price", BigDecimal.class.getName()
+ ));
+
+ /** */
+ private static final Map<String, Object> DFLT_FIELD_VALUES = Map.of(
+ "name", "unknown",
+ "price", new BigDecimal("9.99"),
+ "id", 42);
+
/** */
private final Marshaller marsh = jdk();
/** */
- private final MessageFactory msgFactory = new IgniteMessageFactoryImpl(
+ private final MessageFactory<?> msgFactory = new
IgniteMessageFactoryImpl<>(
new MessageFactoryProvider[] {new CoreMessagesProvider(marsh, marsh)});
/** */
@@ -89,6 +104,34 @@ public class QueryEntityMessageSerializationTest extends
GridCommonAbstractTest
assertEquals(entity.fillAbsentPKsWithDefaults(),
((QueryEntityEx)res).fillAbsentPKsWithDefaults());
}
+ /**
+ * Tests that {@code defaultFieldValues} survive serialization round-trip
through
+ * {@link SchemaAddQueryEntityOperation}, which wraps {@link QueryEntity}
in
+ * {@link QueryEntityMessage} and serializes via eager collection
traversal.
+ */
+ @Test
+ public void testSchemaAddQueryEntityOperationWithDefaultFieldValues()
throws IgniteCheckedException {
+ QueryEntity firstEntity = new QueryEntity()
+ .setFields(FIELDS)
+ .setNotNullFields(Set.of("id"))
+ .setDefaultFieldValues(DFLT_FIELD_VALUES);
+
+ QueryEntity secondEntity = new
QueryEntity(firstEntity).setNotNullFields(Set.of("name"));
+
+ List<QueryEntity> restored = (List<QueryEntity>)writeAndReadBack(
+ new SchemaAddQueryEntityOperation(UUID.randomUUID(), "testCache",
"PUBLIC",
+ List.of(firstEntity, secondEntity), 1, false), 6).entities();
+
+ assertEquals(2, restored.size());
+
+ for (QueryEntity entity : restored) {
+ Map<String, Object> vals = entity.getDefaultFieldValues();
+
+ assertNotNull("defaultFieldValues must not be null after
round-trip", vals);
+ assertEquals(DFLT_FIELD_VALUES, vals);
+ }
+ }
+
/**
* @param src Source entity.
* @param expReadsWritesCnt Expected count of field reads and writes.
@@ -158,26 +201,18 @@ public class QueryEntityMessageSerializationTest extends
GridCommonAbstractTest
/** @return Query entity with every field populated, including non-empty
default field values. */
private QueryEntity queryEntity() {
- LinkedHashMap<String, String> fields = new LinkedHashMap<>();
- fields.put("id", Integer.class.getName());
- fields.put("name", String.class.getName());
- fields.put("price", BigDecimal.class.getName());
-
return new QueryEntity()
.setKeyType(Integer.class.getName())
.setValueType("org.apache.ignite.Person")
.setKeyFieldName("id")
.setValueFieldName("name")
.setTableName("PERSON")
- .setFields(fields)
+ .setFields(FIELDS)
.setKeyFields(Set.of("id"))
.setAliases(Map.of("name", "NAME_ALIAS"))
.setIndexes(List.of(new QueryIndex("name",
QueryIndexType.SORTED).setInlineSize(32)))
.setNotNullFields(Set.of("id", "name"))
- .setDefaultFieldValues(Map.of(
- "name", "unknown",
- "price", new BigDecimal("9.99"),
- "id", 42))
+ .setDefaultFieldValues(DFLT_FIELD_VALUES)
.setFieldsPrecision(Map.of("name", 64))
.setFieldsScale(Map.of("price", 2));
}