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));
     }

Reply via email to