You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ib...@apache.org on 2025/06/03 13:18:30 UTC

(ignite-3) branch main updated: IGNITE-25569 Replace enum ordinals with explicit IDs in messaging serialization (#5968)

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

ibessonov 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 c22d9b16769 IGNITE-25569 Replace enum ordinals with explicit IDs in messaging serialization (#5968)
c22d9b16769 is described below

commit c22d9b16769b2715be65705bbd37bca2d41928bd
Author: Viacheslav Blinov <da...@users.noreply.github.com>
AuthorDate: Tue Jun 3 16:18:23 2025 +0300

    IGNITE-25569 Replace enum ordinals with explicit IDs in messaging serialization (#5968)
---
 .../metastorage/dsl/CompoundConditionType.java     |  31 +++--
 .../internal/metastorage/dsl/ConditionType.java    |  73 +++++++-----
 .../internal/metastorage/dsl/OperationType.java    |  33 ++++--
 .../metastorage/dsl/CompoundConditionTypeTest.java |  38 +++++--
 .../metastorage/dsl/ConditionTypeTest.java         | 106 +++++++----------
 .../metastorage/dsl/OperationTypeTest.java         |  43 ++++---
 .../MessageDeserializerGenerator.java              |  18 +--
 .../serialization/MessageSerializerGenerator.java  |  26 ++++-
 .../internal/network/annotations/Transferable.java |   6 +-
 .../ignite/internal/network/messages/TestEnum.java |  35 ++++--
 .../network/disaster/LocalPartitionStateEnum.java  |  45 +++++---
 .../network/replication/RequestType.java           |  82 +++++++++-----
 .../disaster/LocalPartitionStateEnumTest.java      |  43 ++++---
 .../network/replication/RequestTypeTest.java       | 125 +++++++++++++++------
 .../ignite/raft/jraft/entity/EnumOutter.java       |  23 ++--
 .../ignite/raft/jraft/entity/EntryTypeTest.java    |  16 +--
 .../replicator/action/RequestTypeTest.java         | 122 --------------------
 .../ignite/internal/tx/TxMetaSerializer.java       |   4 +-
 .../org/apache/ignite/internal/tx/TxState.java     |  42 ++++---
 .../org/apache/ignite/internal/tx/TxStateTest.java |  40 +++++--
 20 files changed, 527 insertions(+), 424 deletions(-)

diff --git a/modules/metastorage-api/src/main/java/org/apache/ignite/internal/metastorage/dsl/CompoundConditionType.java b/modules/metastorage-api/src/main/java/org/apache/ignite/internal/metastorage/dsl/CompoundConditionType.java
index 7012763f41f..ba0865c0762 100644
--- a/modules/metastorage-api/src/main/java/org/apache/ignite/internal/metastorage/dsl/CompoundConditionType.java
+++ b/modules/metastorage-api/src/main/java/org/apache/ignite/internal/metastorage/dsl/CompoundConditionType.java
@@ -21,23 +21,32 @@ package org.apache.ignite.internal.metastorage.dsl;
  * Type of compound condition.
  */
 public enum CompoundConditionType {
-    AND,
-    OR;
+    AND(0),
+    OR(1);
 
-    /** Cached array with all enum values. */
-    private static final CompoundConditionType[] VALUES = values();
+
+    private final int id;
+
+    CompoundConditionType(int id) {
+        this.id = id;
+    }
 
     /**
-     * Returns the enumerated value from its ordinal.
+     * Returns the enumerated value from its id.
      *
-     * @param ordinal Ordinal of enumeration constant.
-     * @throws IllegalArgumentException If no enumeration constant by ordinal.
+     * @param id Id of enumeration constant.
+     * @throws IllegalArgumentException If no enumeration constant by id.
      */
-    public static CompoundConditionType fromOrdinal(int ordinal) throws IllegalArgumentException {
-        if (ordinal < 0 || ordinal >= VALUES.length) {
-            throw new IllegalArgumentException("No enum constant from ordinal: " + ordinal);
+    public static CompoundConditionType fromId(int id) throws IllegalArgumentException {
+        switch (id) {
+            case 0: return AND;
+            case 1: return OR;
+            default:
+                throw new IllegalArgumentException("No enum constant from id: " + id);
         }
+    }
 
-        return VALUES[ordinal];
+    public int id() {
+        return id;
     }
 }
diff --git a/modules/metastorage-api/src/main/java/org/apache/ignite/internal/metastorage/dsl/ConditionType.java b/modules/metastorage-api/src/main/java/org/apache/ignite/internal/metastorage/dsl/ConditionType.java
index 34000371efb..b3f0f313562 100644
--- a/modules/metastorage-api/src/main/java/org/apache/ignite/internal/metastorage/dsl/ConditionType.java
+++ b/modules/metastorage-api/src/main/java/org/apache/ignite/internal/metastorage/dsl/ConditionType.java
@@ -22,67 +22,90 @@ package org.apache.ignite.internal.metastorage.dsl;
  */
 public enum ConditionType {
     /** Equality condition type for a revision. */
-    REV_EQUAL,
+    REV_EQUAL(0),
 
     /** Inequality condition type for a revision. */
-    REV_NOT_EQUAL,
+    REV_NOT_EQUAL(1),
 
     /** Greater than condition type for a revision. */
-    REV_GREATER,
+    REV_GREATER(2),
 
     /** Less than condition type for a revision. */
-    REV_LESS,
+    REV_LESS(3),
 
     /** Less than or equal to condition type for a revision. */
-    REV_LESS_OR_EQUAL,
+    REV_LESS_OR_EQUAL(4),
 
     /** Greater than or equal to condition type for a revision. */
-    REV_GREATER_OR_EQUAL,
+    REV_GREATER_OR_EQUAL(5),
 
     /** Equality condition type for a value. */
-    VAL_EQUAL,
+    VAL_EQUAL(6),
 
     /** Inequality condition type for a value. */
-    VAL_NOT_EQUAL,
+    VAL_NOT_EQUAL(7),
 
     /** Greater than condition type for a value. */
-    VAL_GREATER,
+    VAL_GREATER(8),
 
     /** Less than condition type for a value. */
-    VAL_LESS,
+    VAL_LESS(9),
 
     /** Less than or equal to condition type for a value. */
-    VAL_LESS_OR_EQUAL,
+    VAL_LESS_OR_EQUAL(10),
 
     /** Greater than or equal to condition type for a value. */
-    VAL_GREATER_OR_EQUAL,
+    VAL_GREATER_OR_EQUAL(11),
 
     /** Existence condition type for a key. */
-    KEY_EXISTS,
+    KEY_EXISTS(12),
 
     /** Non-existence condition type for a key. */
-    KEY_NOT_EXISTS,
+    KEY_NOT_EXISTS(13),
 
     /** Tombstone condition type for a key. */
-    TOMBSTONE,
+    TOMBSTONE(14),
 
     /** Not-tombstone condition type for a key. */
-    NOT_TOMBSTONE;
+    NOT_TOMBSTONE(15);
 
-    /** Cached array with all enum values. */
-    private static final ConditionType[] VALUES = values();
+
+    private final int id;
+
+    ConditionType(int id) {
+        this.id = id;
+    }
 
     /**
-     * Returns the enumerated value from its ordinal.
+     * Returns the enumerated value from its id.
      *
-     * @param ordinal Ordinal of enumeration constant.
-     * @throws IllegalArgumentException If no enumeration constant by ordinal.
+     * @param id Id of enumeration constant.
+     * @throws IllegalArgumentException If no enumeration constant by id.
      */
-    public static ConditionType fromOrdinal(int ordinal) throws IllegalArgumentException {
-        if (ordinal < 0 || ordinal >= VALUES.length) {
-            throw new IllegalArgumentException("No enum constant from ordinal: " + ordinal);
+    public static ConditionType fromId(int id) throws IllegalArgumentException {
+        switch (id) {
+            case 0: return REV_EQUAL;
+            case 1: return REV_NOT_EQUAL;
+            case 2: return REV_GREATER;
+            case 3: return REV_LESS;
+            case 4: return REV_LESS_OR_EQUAL;
+            case 5: return REV_GREATER_OR_EQUAL;
+            case 6: return VAL_EQUAL;
+            case 7: return VAL_NOT_EQUAL;
+            case 8: return VAL_GREATER;
+            case 9: return VAL_LESS;
+            case 10: return VAL_LESS_OR_EQUAL;
+            case 11: return VAL_GREATER_OR_EQUAL;
+            case 12: return KEY_EXISTS;
+            case 13: return KEY_NOT_EXISTS;
+            case 14: return TOMBSTONE;
+            case 15: return NOT_TOMBSTONE;
+            default:
+                throw new IllegalArgumentException("No enum constant from id: " + id);
         }
+    }
 
-        return VALUES[ordinal];
+    public int id() {
+        return id;
     }
 }
diff --git a/modules/metastorage-api/src/main/java/org/apache/ignite/internal/metastorage/dsl/OperationType.java b/modules/metastorage-api/src/main/java/org/apache/ignite/internal/metastorage/dsl/OperationType.java
index 09579946059..c87b5fc8fcf 100644
--- a/modules/metastorage-api/src/main/java/org/apache/ignite/internal/metastorage/dsl/OperationType.java
+++ b/modules/metastorage-api/src/main/java/org/apache/ignite/internal/metastorage/dsl/OperationType.java
@@ -22,28 +22,37 @@ package org.apache.ignite.internal.metastorage.dsl;
  */
 public enum OperationType {
     /** No-op operation. */
-    NO_OP,
+    NO_OP(0),
 
     /** Put (insert/replace) operation. */
-    PUT,
+    PUT(1),
 
     /** Remove operation. */
-    REMOVE;
+    REMOVE(2);
 
-    /** Cached array with all enum values. */
-    private static final OperationType[] VALUES = values();
+    private final int id;
+
+    OperationType(int id) {
+        this.id = id;
+    }
 
     /**
-     * Returns the enumerated value from its ordinal.
+     * Returns the enumerated value from its id.
      *
-     * @param ordinal Ordinal of enumeration constant.
-     * @throws IllegalArgumentException If no enumeration constant by ordinal.
+     * @param id Id of enumeration constant.
+     * @throws IllegalArgumentException If no enumeration constant by id.
      */
-    public static OperationType fromOrdinal(int ordinal) throws IllegalArgumentException {
-        if (ordinal < 0 || ordinal >= VALUES.length) {
-            throw new IllegalArgumentException("No enum constant from ordinal: " + ordinal);
+    public static OperationType fromId(int id) throws IllegalArgumentException {
+        switch (id) {
+            case 0: return NO_OP;
+            case 1: return PUT;
+            case 2: return REMOVE;
+            default:
+                throw new IllegalArgumentException("No enum constant from id: " + id);
         }
+    }
 
-        return VALUES[ordinal];
+    public int id() {
+        return id;
     }
 }
diff --git a/modules/metastorage-api/src/test/java/org/apache/ignite/internal/metastorage/dsl/CompoundConditionTypeTest.java b/modules/metastorage-api/src/test/java/org/apache/ignite/internal/metastorage/dsl/CompoundConditionTypeTest.java
index 1d7a26e366a..cfc561ff455 100644
--- a/modules/metastorage-api/src/test/java/org/apache/ignite/internal/metastorage/dsl/CompoundConditionTypeTest.java
+++ b/modules/metastorage-api/src/test/java/org/apache/ignite/internal/metastorage/dsl/CompoundConditionTypeTest.java
@@ -19,29 +19,43 @@ package org.apache.ignite.internal.metastorage.dsl;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.params.provider.Arguments.arguments;
 
+import java.util.stream.Stream;
 import org.apache.ignite.internal.network.NetworkMessage;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
 
 /**
- * Tests that persisted enum ordinals have not been accidentally changed by a developer.
+ * Tests that persisted enum IDs have not been accidentally changed by a developer.
  */
 class CompoundConditionTypeTest {
-    @Test
-    void testOrdinal() {
-        assertEquals(0, CompoundConditionType.AND.ordinal());
+    private static Stream<Arguments> conditionTypeIds() {
+        return Stream.of(
+                arguments(CompoundConditionType.AND, 0),
+                arguments(CompoundConditionType.OR, 1)
+        );
+    }
 
-        assertEquals(1, CompoundConditionType.OR.ordinal());
+    @ParameterizedTest
+    @MethodSource("conditionTypeIds")
+    void testId(CompoundConditionType compoundConditionType, int expectedId) {
+        assertEquals(expectedId, compoundConditionType.id());
     }
 
-    /** Checks that the ordinal does not change, since the enum will be transferred in the {@link NetworkMessage}. */
-    @Test
-    void testFromOrdinal() {
-        assertEquals(CompoundConditionType.AND, CompoundConditionType.fromOrdinal(0));
+    /** Checks that the ID does not change, since the enum will be transferred in the {@link NetworkMessage}. */
+    @ParameterizedTest
+    @MethodSource("conditionTypeIds")
+    void testFromId(CompoundConditionType expectedEnumEntry, int id) {
+        assertEquals(expectedEnumEntry, CompoundConditionType.fromId(id));
 
-        assertEquals(CompoundConditionType.OR, CompoundConditionType.fromOrdinal(1));
+    }
 
-        assertThrows(IllegalArgumentException.class, () -> CompoundConditionType.fromOrdinal(-1));
-        assertThrows(IllegalArgumentException.class, () -> CompoundConditionType.fromOrdinal(2));
+    @Test
+    void testFromIdThrows() {
+        assertThrows(IllegalArgumentException.class, () -> CompoundConditionType.fromId(-1));
+        assertThrows(IllegalArgumentException.class, () -> CompoundConditionType.fromId(2));
     }
 }
diff --git a/modules/metastorage-api/src/test/java/org/apache/ignite/internal/metastorage/dsl/ConditionTypeTest.java b/modules/metastorage-api/src/test/java/org/apache/ignite/internal/metastorage/dsl/ConditionTypeTest.java
index aa9fb3b9c37..053552a66cd 100644
--- a/modules/metastorage-api/src/test/java/org/apache/ignite/internal/metastorage/dsl/ConditionTypeTest.java
+++ b/modules/metastorage-api/src/test/java/org/apache/ignite/internal/metastorage/dsl/ConditionTypeTest.java
@@ -19,85 +19,57 @@ package org.apache.ignite.internal.metastorage.dsl;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.params.provider.Arguments.arguments;
 
+import java.util.stream.Stream;
 import org.apache.ignite.internal.network.NetworkMessage;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
 
 /**
- * Tests that persisted enum ordinals have not been accidentally changed by a developer.
+ * Tests that persisted enum IDs have not been accidentally changed by a developer.
  */
 class ConditionTypeTest {
-    @Test
-    void testOrdinal() {
-        assertEquals(0, ConditionType.REV_EQUAL.ordinal());
-
-        assertEquals(1, ConditionType.REV_NOT_EQUAL.ordinal());
-
-        assertEquals(2, ConditionType.REV_GREATER.ordinal());
-
-        assertEquals(3, ConditionType.REV_LESS.ordinal());
-
-        assertEquals(4, ConditionType.REV_LESS_OR_EQUAL.ordinal());
-
-        assertEquals(5, ConditionType.REV_GREATER_OR_EQUAL.ordinal());
-
-        assertEquals(6, ConditionType.VAL_EQUAL.ordinal());
-
-        assertEquals(7, ConditionType.VAL_NOT_EQUAL.ordinal());
-
-        assertEquals(8, ConditionType.VAL_GREATER.ordinal());
-
-        assertEquals(9, ConditionType.VAL_LESS.ordinal());
-
-        assertEquals(10, ConditionType.VAL_LESS_OR_EQUAL.ordinal());
-
-        assertEquals(11, ConditionType.VAL_GREATER_OR_EQUAL.ordinal());
-
-        assertEquals(12, ConditionType.KEY_EXISTS.ordinal());
+    private static Stream<Arguments> conditionTypeIds() {
+        return Stream.of(
+                arguments(ConditionType.REV_EQUAL, 0),
+                arguments(ConditionType.REV_NOT_EQUAL, 1),
+                arguments(ConditionType.REV_GREATER, 2),
+                arguments(ConditionType.REV_LESS, 3),
+                arguments(ConditionType.REV_LESS_OR_EQUAL, 4),
+                arguments(ConditionType.REV_GREATER_OR_EQUAL, 5),
+                arguments(ConditionType.VAL_EQUAL, 6),
+                arguments(ConditionType.VAL_NOT_EQUAL, 7),
+                arguments(ConditionType.VAL_GREATER, 8),
+                arguments(ConditionType.VAL_LESS, 9),
+                arguments(ConditionType.VAL_LESS_OR_EQUAL, 10),
+                arguments(ConditionType.VAL_GREATER_OR_EQUAL, 11),
+                arguments(ConditionType.KEY_EXISTS, 12),
+                arguments(ConditionType.KEY_NOT_EXISTS, 13),
+                arguments(ConditionType.TOMBSTONE, 14),
+                arguments(ConditionType.NOT_TOMBSTONE, 15)
+        );
+    }
 
-        assertEquals(13, ConditionType.KEY_NOT_EXISTS.ordinal());
+    @ParameterizedTest
+    @MethodSource("conditionTypeIds")
+    void testId(ConditionType conditionType, int expectedId) {
+        assertEquals(expectedId, conditionType.id());
+    }
 
-        assertEquals(14, ConditionType.TOMBSTONE.ordinal());
+    /** Checks that the ID does not change, since the enum will be transferred in the {@link NetworkMessage}. */
+    @ParameterizedTest
+    @MethodSource("conditionTypeIds")
+    void testFromId(ConditionType expectedEnumEntry, int id) {
+        assertEquals(expectedEnumEntry, ConditionType.fromId(id));
 
-        assertEquals(15, ConditionType.NOT_TOMBSTONE.ordinal());
     }
 
-    /** Checks that the ordinal does not change, since the enum will be transferred in the {@link NetworkMessage}. */
     @Test
-    void testFromOrdinal() {
-        assertEquals(ConditionType.REV_EQUAL, ConditionType.fromOrdinal(0));
-
-        assertEquals(ConditionType.REV_NOT_EQUAL, ConditionType.fromOrdinal(1));
-
-        assertEquals(ConditionType.REV_GREATER, ConditionType.fromOrdinal(2));
-
-        assertEquals(ConditionType.REV_LESS, ConditionType.fromOrdinal(3));
-
-        assertEquals(ConditionType.REV_LESS_OR_EQUAL, ConditionType.fromOrdinal(4));
-
-        assertEquals(ConditionType.REV_GREATER_OR_EQUAL, ConditionType.fromOrdinal(5));
-
-        assertEquals(ConditionType.VAL_EQUAL, ConditionType.fromOrdinal(6));
-
-        assertEquals(ConditionType.VAL_NOT_EQUAL, ConditionType.fromOrdinal(7));
-
-        assertEquals(ConditionType.VAL_GREATER, ConditionType.fromOrdinal(8));
-
-        assertEquals(ConditionType.VAL_LESS, ConditionType.fromOrdinal(9));
-
-        assertEquals(ConditionType.VAL_LESS_OR_EQUAL, ConditionType.fromOrdinal(10));
-
-        assertEquals(ConditionType.VAL_GREATER_OR_EQUAL, ConditionType.fromOrdinal(11));
-
-        assertEquals(ConditionType.KEY_EXISTS, ConditionType.fromOrdinal(12));
-
-        assertEquals(ConditionType.KEY_NOT_EXISTS, ConditionType.fromOrdinal(13));
-
-        assertEquals(ConditionType.TOMBSTONE, ConditionType.fromOrdinal(14));
-
-        assertEquals(ConditionType.NOT_TOMBSTONE, ConditionType.fromOrdinal(15));
-
-        assertThrows(IllegalArgumentException.class, () -> ConditionType.fromOrdinal(-1));
-        assertThrows(IllegalArgumentException.class, () -> ConditionType.fromOrdinal(16));
+    void testFromIdThrows() {
+        assertThrows(IllegalArgumentException.class, () -> ConditionType.fromId(-1));
+        assertThrows(IllegalArgumentException.class, () -> ConditionType.fromId(16));
     }
 }
diff --git a/modules/metastorage-api/src/test/java/org/apache/ignite/internal/metastorage/dsl/OperationTypeTest.java b/modules/metastorage-api/src/test/java/org/apache/ignite/internal/metastorage/dsl/OperationTypeTest.java
index cfbbe3369bc..e18dca5e1a4 100644
--- a/modules/metastorage-api/src/test/java/org/apache/ignite/internal/metastorage/dsl/OperationTypeTest.java
+++ b/modules/metastorage-api/src/test/java/org/apache/ignite/internal/metastorage/dsl/OperationTypeTest.java
@@ -19,33 +19,44 @@ package org.apache.ignite.internal.metastorage.dsl;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.params.provider.Arguments.arguments;
 
+import java.util.stream.Stream;
 import org.apache.ignite.internal.network.NetworkMessage;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
 
 /**
- * Tests that persisted enum ordinals have not been accidentally changed by a developer.
+ * Tests that persisted enum IDs have not been accidentally changed by a developer.
  */
 class OperationTypeTest {
-    @Test
-    void testOrdinal() {
-        assertEquals(0, OperationType.NO_OP.ordinal());
-
-        assertEquals(1, OperationType.PUT.ordinal());
-
-        assertEquals(2, OperationType.REMOVE.ordinal());
+    private static Stream<Arguments> operationIds() {
+        return Stream.of(
+                arguments(OperationType.NO_OP, 0),
+                arguments(OperationType.PUT, 1),
+                arguments(OperationType.REMOVE, 2)
+        );
     }
 
-    /** Checks that the ordinal does not change, since the enum will be transferred in the {@link NetworkMessage}. */
-    @Test
-    void testFromOrdinal() {
-        assertEquals(OperationType.NO_OP, OperationType.fromOrdinal(0));
+    @ParameterizedTest
+    @MethodSource("operationIds")
+    void testId(OperationType operationType, int expectedId) {
+        assertEquals(expectedId, operationType.id());
+    }
 
-        assertEquals(OperationType.PUT, OperationType.fromOrdinal(1));
+    /** Checks that the ID does not change, since the enum will be transferred in the {@link NetworkMessage}. */
+    @ParameterizedTest
+    @MethodSource("operationIds")
+    void testFromId(OperationType expectedOperationType, int id) {
+        assertEquals(expectedOperationType, OperationType.fromId(id));
 
-        assertEquals(OperationType.REMOVE, OperationType.fromOrdinal(2));
+    }
 
-        assertThrows(IllegalArgumentException.class, () -> OperationType.fromOrdinal(-1));
-        assertThrows(IllegalArgumentException.class, () -> OperationType.fromOrdinal(3));
+    @Test
+    void testFromIdThrows() {
+        assertThrows(IllegalArgumentException.class, () -> OperationType.fromId(-1));
+        assertThrows(IllegalArgumentException.class, () -> OperationType.fromId(3));
     }
 }
diff --git a/modules/network-annotation-processor/src/main/java/org/apache/ignite/internal/network/processor/serialization/MessageDeserializerGenerator.java b/modules/network-annotation-processor/src/main/java/org/apache/ignite/internal/network/processor/serialization/MessageDeserializerGenerator.java
index 4679260db1b..610fc54de5a 100644
--- a/modules/network-annotation-processor/src/main/java/org/apache/ignite/internal/network/processor/serialization/MessageDeserializerGenerator.java
+++ b/modules/network-annotation-processor/src/main/java/org/apache/ignite/internal/network/processor/serialization/MessageDeserializerGenerator.java
@@ -49,7 +49,7 @@ import org.apache.ignite.internal.network.serialization.MessageReader;
  * Class for generating {@link MessageDeserializer} classes.
  */
 public class MessageDeserializerGenerator {
-    private static final String FROM_ORDINAL_METHOD_NAME = "fromOrdinal";
+    private static final String FROM_ID_METHOD_NAME = "fromId";
 
     /** Processing environment. */
     private final ProcessingEnvironment processingEnv;
@@ -151,11 +151,11 @@ public class MessageDeserializerGenerator {
                 method.beginControlFlow("case $L:", i);
 
                 if (typeUtils.isEnum(getter.getReturnType())) {
-                    checkFromOrdinalMethodExists(getter.getReturnType());
+                    checkFromIdMethodExists(getter.getReturnType());
 
-                    // At the beginning we read the shifted ordinal, shifted by +1 to efficiently transfer null (since we use "var int").
+                    // At the beginning we read the shifted ID, shifted by +1 to efficiently transfer null (since we use "var int").
                     // If we read garbage then we should not convert to an enumeration, the check below does this.
-                    method.addStatement("int ordinalShifted = reader.readInt($S)", getterName);
+                    method.addStatement("int shiftedId = reader.readInt($S)", getterName);
                 } else {
                     method.addStatement(readMessageCodeBlock(getter));
                 }
@@ -175,8 +175,8 @@ public class MessageDeserializerGenerator {
 
                     method
                             .addStatement(
-                                    "$T tmp = ordinalShifted == 0 ? null : $T.$L(ordinalShifted - 1)",
-                                    varType, varType, FROM_ORDINAL_METHOD_NAME
+                                    "$T tmp = shiftedId == 0 ? null : $T.$L(shiftedId - 1)",
+                                    varType, varType, FROM_ID_METHOD_NAME
                             )
                             .addCode("\n");
                 }
@@ -214,17 +214,17 @@ public class MessageDeserializerGenerator {
                 .build();
     }
 
-    private void checkFromOrdinalMethodExists(TypeMirror enumType) {
+    private void checkFromIdMethodExists(TypeMirror enumType) {
         assert typeUtils.isEnum(enumType) : enumType;
 
         typeUtils.types().asElement(enumType).getEnclosedElements().stream()
                 .filter(element -> element.getKind() == ElementKind.METHOD)
-                .filter(element -> element.getSimpleName().toString().equals(FROM_ORDINAL_METHOD_NAME))
+                .filter(element -> element.getSimpleName().toString().equals(FROM_ID_METHOD_NAME))
                 .filter(element -> element.getModifiers().contains(Modifier.PUBLIC))
                 .filter(element -> element.getModifiers().contains(Modifier.STATIC))
                 .findAny()
                 .orElseThrow(() -> new ProcessingException(
-                        String.format("Missing public static method \"%s\" for enum %s", FROM_ORDINAL_METHOD_NAME, enumType)
+                        String.format("Missing public static method \"%s\" for enum %s", FROM_ID_METHOD_NAME, enumType)
                 ));
     }
 }
diff --git a/modules/network-annotation-processor/src/main/java/org/apache/ignite/internal/network/processor/serialization/MessageSerializerGenerator.java b/modules/network-annotation-processor/src/main/java/org/apache/ignite/internal/network/processor/serialization/MessageSerializerGenerator.java
index efb558783fb..4d6d12933e9 100644
--- a/modules/network-annotation-processor/src/main/java/org/apache/ignite/internal/network/processor/serialization/MessageSerializerGenerator.java
+++ b/modules/network-annotation-processor/src/main/java/org/apache/ignite/internal/network/processor/serialization/MessageSerializerGenerator.java
@@ -27,13 +27,16 @@ import com.squareup.javapoet.ParameterizedTypeName;
 import com.squareup.javapoet.TypeSpec;
 import java.util.List;
 import javax.annotation.processing.ProcessingEnvironment;
+import javax.lang.model.element.ElementKind;
 import javax.lang.model.element.ExecutableElement;
 import javax.lang.model.element.Modifier;
+import javax.lang.model.type.TypeMirror;
 import javax.tools.Diagnostic;
 import org.apache.ignite.internal.network.NetworkMessage;
 import org.apache.ignite.internal.network.annotations.Transient;
 import org.apache.ignite.internal.network.processor.MessageClass;
 import org.apache.ignite.internal.network.processor.MessageGroupWrapper;
+import org.apache.ignite.internal.network.processor.ProcessingException;
 import org.apache.ignite.internal.network.processor.TypeUtils;
 import org.apache.ignite.internal.network.serialization.MessageMappingException;
 import org.apache.ignite.internal.network.serialization.MessageSerializer;
@@ -43,6 +46,8 @@ import org.apache.ignite.internal.network.serialization.MessageWriter;
  * Class for generating {@link MessageSerializer} classes.
  */
 public class MessageSerializerGenerator {
+    private static final String ID_METHOD_NAME = "id";
+
     /** Processing environment. */
     private final ProcessingEnvironment processingEnv;
 
@@ -150,11 +155,13 @@ public class MessageSerializerGenerator {
         if (typeUtils.isEnum(getter.getReturnType())) {
             String fieldName = getter.getSimpleName().toString();
 
-            // Let's write the shifted ordinal to efficiently transfer null (since we use "var int").
+            checkIdMethodExists(getter.getReturnType());
+
+            // Let's write the shifted id to efficiently transfer null (since we use "var int").
             writerMethodCallBuilder
-                    .add("int ordinalShifted = message.$L() == null ? 0 : message.$L().ordinal() + 1;", fieldName, fieldName)
+                    .add("int idShifted = message.$L() == null ? 0 : message.$L().id() + 1;", fieldName, fieldName)
                     .add("\n")
-                    .add("boolean written = writer.writeInt($S, ordinalShifted)", fieldName);
+                    .add("boolean written = writer.writeInt($S, idShifted)", fieldName);
         } else {
             writerMethodCallBuilder
                     .add("boolean written = writer.")
@@ -169,4 +176,17 @@ public class MessageSerializerGenerator {
                 .endControlFlow()
                 .build();
     }
+
+    private void checkIdMethodExists(TypeMirror enumType) {
+        assert typeUtils.isEnum(enumType) : enumType;
+
+        typeUtils.types().asElement(enumType).getEnclosedElements().stream()
+                .filter(element -> element.getKind() == ElementKind.METHOD)
+                .filter(element -> element.getSimpleName().toString().equals(ID_METHOD_NAME))
+                .filter(element -> element.getModifiers().contains(Modifier.PUBLIC))
+                .findAny()
+                .orElseThrow(() -> new ProcessingException(
+                        String.format("Missing public method \"%s\" for enum %s", ID_METHOD_NAME, enumType)
+                ));
+    }
 }
diff --git a/modules/network-api/src/main/java/org/apache/ignite/internal/network/annotations/Transferable.java b/modules/network-api/src/main/java/org/apache/ignite/internal/network/annotations/Transferable.java
index b31e3d316ef..1aa16cc35b9 100644
--- a/modules/network-api/src/main/java/org/apache/ignite/internal/network/annotations/Transferable.java
+++ b/modules/network-api/src/main/java/org/apache/ignite/internal/network/annotations/Transferable.java
@@ -74,8 +74,10 @@ import org.apache.ignite.internal.network.serialization.MessageSerializer;
  *     <li>{@code Collection} of boxed primitive types or other directly marshallable types;</li>
  *     <li>{@code Map} where both keys and values can be of a directly marshallable type.</li>
  *     <li>{@link HybridTimestamp}.</li>
- *     <li>{@link Enum} that must contain the method "public static SomeEnum fromOrdinal(int ordinal) @throws IllegalArgumentException ".
- *     </li>
+ *     <li>{@link Enum} that must contain the methods:<ol>
+ *         <li>public static SomeEnum fromId(int id) @throws IllegalArgumentException</li>
+ *         <li>public int id()</li>
+ *     </ol></li>
  * </ol>
  *
  * <p>After all marked interfaces in a module have been processed, the processor will use the
diff --git a/modules/network/src/testFixtures/java/org/apache/ignite/internal/network/messages/TestEnum.java b/modules/network/src/testFixtures/java/org/apache/ignite/internal/network/messages/TestEnum.java
index 7b9edf3aebb..bf45c13d3a5 100644
--- a/modules/network/src/testFixtures/java/org/apache/ignite/internal/network/messages/TestEnum.java
+++ b/modules/network/src/testFixtures/java/org/apache/ignite/internal/network/messages/TestEnum.java
@@ -19,24 +19,39 @@ package org.apache.ignite.internal.network.messages;
 
 /** Test enum. */
 public enum TestEnum {
-    ONE,
-    TWO,
-    THREE;
+    ONE(0),
+    TWO(1),
+    THREE(2);
+
+    private final int id;
+
+    TestEnum(int id) {
+        this.id = id;
+    }
 
     /** Cached array with all enum values. */
     private static final TestEnum[] VALUES = values();
 
     /**
-     * Returns the enumerated value from its ordinal.
+     * Returns the enumerated value from its id.
      *
-     * @param ordinal Ordinal of enumeration constant.
-     * @throws IllegalArgumentException If no enumeration constant by ordinal.
+     * @param id Id of enumeration constant.
+     * @throws IllegalArgumentException If no enumeration constant by id.
      */
-    public static TestEnum fromOrdinal(int ordinal) throws IllegalArgumentException {
-        if (ordinal < 0 || ordinal >= VALUES.length) {
-            throw new IllegalArgumentException("No enum constant from ordinal: " + ordinal);
+    public static TestEnum fromId(int id) throws IllegalArgumentException {
+        if (id < 0) {
+            throw new IllegalArgumentException("No enum constant from id: " + id);
         }
 
-        return VALUES[ordinal];
+        for (TestEnum testEnum : VALUES) {
+            if (testEnum.id == id) {
+                return testEnum;
+            }
+        }
+        throw new IllegalArgumentException("No enum constant from id: " + id);
+    }
+
+    public int id() {
+        return id;
     }
 }
diff --git a/modules/partition-replicator/src/main/java/org/apache/ignite/internal/partition/replicator/network/disaster/LocalPartitionStateEnum.java b/modules/partition-replicator/src/main/java/org/apache/ignite/internal/partition/replicator/network/disaster/LocalPartitionStateEnum.java
index feccb68b844..453b3602eb6 100644
--- a/modules/partition-replicator/src/main/java/org/apache/ignite/internal/partition/replicator/network/disaster/LocalPartitionStateEnum.java
+++ b/modules/partition-replicator/src/main/java/org/apache/ignite/internal/partition/replicator/network/disaster/LocalPartitionStateEnum.java
@@ -24,25 +24,22 @@ import org.apache.ignite.raft.jraft.core.State;
  */
 public enum LocalPartitionStateEnum {
     /** This state might be used when partition is not yet started, or it's already stopping, for example. */
-    UNAVAILABLE,
+    UNAVAILABLE(0),
 
     /** Alive partition with a healthy state machine. */
-    HEALTHY,
+    HEALTHY(1),
 
     /** Partition is starting right now. */
-    INITIALIZING,
+    INITIALIZING(2),
 
     /** Partition is installing a Raft snapshot from the leader. */
-    INSTALLING_SNAPSHOT,
+    INSTALLING_SNAPSHOT(3),
 
     /** Partition is catching up, meaning that it's not replicated part of the log yet. */
-    CATCHING_UP,
+    CATCHING_UP(4),
 
     /** Partition is in broken state, usually it means that its state machine thrown an exception. */
-    BROKEN;
-
-    /** Cached array with all enum values. */
-    private static final LocalPartitionStateEnum[] VALUES = values();
+    BROKEN(5);
 
     /** Converts internal raft node state into public local partition state. */
     public static LocalPartitionStateEnum convert(State raftNodeState) {
@@ -70,17 +67,33 @@ public enum LocalPartitionStateEnum {
         }
     }
 
+
+    private final int id;
+
+    LocalPartitionStateEnum(int id) {
+        this.id = id;
+    }
+
     /**
-     * Returns the enumerated value from its ordinal.
+     * Returns the enumerated value from its id.
      *
-     * @param ordinal Ordinal of enumeration constant.
-     * @throws IllegalArgumentException If no enumeration constant by ordinal.
+     * @param id Id of enumeration constant.
+     * @throws IllegalArgumentException If no enumeration constant by id.
      */
-    public static LocalPartitionStateEnum fromOrdinal(int ordinal) throws IllegalArgumentException {
-        if (ordinal < 0 || ordinal >= VALUES.length) {
-            throw new IllegalArgumentException("No enum constant from ordinal: " + ordinal);
+    public static LocalPartitionStateEnum fromId(int id) throws IllegalArgumentException {
+        switch (id) {
+            case 0: return UNAVAILABLE;
+            case 1: return HEALTHY;
+            case 2: return INITIALIZING;
+            case 3: return INSTALLING_SNAPSHOT;
+            case 4: return CATCHING_UP;
+            case 5: return BROKEN;
+            default:
+                throw new IllegalArgumentException("No enum constant from id: " + id);
         }
+    }
 
-        return VALUES[ordinal];
+    public int id() {
+        return id;
     }
 }
diff --git a/modules/partition-replicator/src/main/java/org/apache/ignite/internal/partition/replicator/network/replication/RequestType.java b/modules/partition-replicator/src/main/java/org/apache/ignite/internal/partition/replicator/network/replication/RequestType.java
index 8b527dfc345..6a9debf4983 100644
--- a/modules/partition-replicator/src/main/java/org/apache/ignite/internal/partition/replicator/network/replication/RequestType.java
+++ b/modules/partition-replicator/src/main/java/org/apache/ignite/internal/partition/replicator/network/replication/RequestType.java
@@ -21,43 +21,53 @@ package org.apache.ignite.internal.partition.replicator.network.replication;
  * Transaction operation type.
  */
 public enum RequestType {
-    RW_GET,
+    RW_GET(0),
 
-    RW_GET_ALL,
+    RW_GET_ALL(1),
 
-    RW_DELETE,
+    RW_DELETE(2),
 
-    RW_DELETE_ALL,
+    RW_DELETE_ALL(3),
 
-    RW_DELETE_EXACT,
+    RW_DELETE_EXACT(4),
 
-    RW_DELETE_EXACT_ALL,
+    RW_DELETE_EXACT_ALL(5),
 
-    RW_INSERT,
+    RW_INSERT(6),
 
-    RW_INSERT_ALL,
+    RW_INSERT_ALL(7),
 
-    RW_UPSERT,
+    RW_UPSERT(8),
 
-    RW_UPSERT_ALL,
+    RW_UPSERT_ALL(9),
 
-    RW_REPLACE,
+    RW_REPLACE(10),
 
-    RW_REPLACE_IF_EXIST,
+    RW_REPLACE_IF_EXIST(11),
 
-    RW_GET_AND_DELETE,
+    RW_GET_AND_DELETE(12),
 
-    RW_GET_AND_REPLACE,
+    RW_GET_AND_REPLACE(13),
 
-    RW_GET_AND_UPSERT,
+    RW_GET_AND_UPSERT(14),
 
-    RW_SCAN,
+    RW_SCAN(15),
 
-    RO_GET,
+    RO_GET(16),
 
-    RO_GET_ALL,
+    RO_GET_ALL(17),
 
-    RO_SCAN;
+    RO_SCAN(18);
+
+    private final int requestTypeId;
+
+    RequestType(int id) {
+        this.requestTypeId = id;
+    }
+
+    public int id() {
+        return requestTypeId;
+    }
 
     /** Cached array with all enum values. */
     private static final RequestType[] VALUES = values();
@@ -101,16 +111,34 @@ public enum RequestType {
     }
 
     /**
-     * Returns the enumerated value from its ordinal.
+     * Returns the enumerated value from its id.
      *
-     * @param ordinal Ordinal of enumeration constant.
-     * @throws IllegalArgumentException If no enumeration constant by ordinal.
+     * @param requestTypeId Id of request type.
+     * @throws IllegalArgumentException If there is no request type with such id.
      */
-    public static RequestType fromOrdinal(int ordinal) throws IllegalArgumentException {
-        if (ordinal < 0 || ordinal >= VALUES.length) {
-            throw new IllegalArgumentException("No enum constant from ordinal: " + ordinal);
+    public static RequestType fromId(int requestTypeId) throws IllegalArgumentException {
+        switch (requestTypeId) {
+            case 0: return RW_GET;
+            case 1: return RW_GET_ALL;
+            case 2: return RW_DELETE;
+            case 3: return RW_DELETE_ALL;
+            case 4: return RW_DELETE_EXACT;
+            case 5: return RW_DELETE_EXACT_ALL;
+            case 6: return RW_INSERT;
+            case 7: return RW_INSERT_ALL;
+            case 8: return RW_UPSERT;
+            case 9: return RW_UPSERT_ALL;
+            case 10: return RW_REPLACE;
+            case 11: return RW_REPLACE_IF_EXIST;
+            case 12: return RW_GET_AND_DELETE;
+            case 13: return RW_GET_AND_REPLACE;
+            case 14: return RW_GET_AND_UPSERT;
+            case 15: return RW_SCAN;
+            case 16: return RO_GET;
+            case 17: return RO_GET_ALL;
+            case 18: return RO_SCAN;
+            default:
+                throw new IllegalArgumentException("No enum constant from id: " + requestTypeId);
         }
-
-        return VALUES[ordinal];
     }
 }
diff --git a/modules/partition-replicator/src/test/java/org/apache/ignite/internal/partition/replicator/network/disaster/LocalPartitionStateEnumTest.java b/modules/partition-replicator/src/test/java/org/apache/ignite/internal/partition/replicator/network/disaster/LocalPartitionStateEnumTest.java
index c5f6f61dbb5..8e2f0823a44 100644
--- a/modules/partition-replicator/src/test/java/org/apache/ignite/internal/partition/replicator/network/disaster/LocalPartitionStateEnumTest.java
+++ b/modules/partition-replicator/src/test/java/org/apache/ignite/internal/partition/replicator/network/disaster/LocalPartitionStateEnumTest.java
@@ -19,28 +19,45 @@ package org.apache.ignite.internal.partition.replicator.network.disaster;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.params.provider.Arguments.arguments;
 
+import java.util.stream.Stream;
 import org.apache.ignite.internal.network.NetworkMessage;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
 
 /** For {@link LocalPartitionStateEnum} testing. */
 public class LocalPartitionStateEnumTest {
-    /** Checks that the ordinal does not change, since the enum will be transferred in the {@link NetworkMessage}. */
-    @Test
-    void testFromOrdinal() {
-        assertEquals(LocalPartitionStateEnum.UNAVAILABLE, LocalPartitionStateEnum.fromOrdinal(0));
-
-        assertEquals(LocalPartitionStateEnum.HEALTHY, LocalPartitionStateEnum.fromOrdinal(1));
-
-        assertEquals(LocalPartitionStateEnum.INITIALIZING, LocalPartitionStateEnum.fromOrdinal(2));
+    private static Stream<Arguments> conditionTypeIds() {
+        return Stream.of(
+                arguments(LocalPartitionStateEnum.UNAVAILABLE, 0),
+                arguments(LocalPartitionStateEnum.HEALTHY, 1),
+                arguments(LocalPartitionStateEnum.INITIALIZING, 2),
+                arguments(LocalPartitionStateEnum.INSTALLING_SNAPSHOT, 3),
+                arguments(LocalPartitionStateEnum.CATCHING_UP, 4),
+                arguments(LocalPartitionStateEnum.BROKEN, 5)
+        );
+    }
 
-        assertEquals(LocalPartitionStateEnum.INSTALLING_SNAPSHOT, LocalPartitionStateEnum.fromOrdinal(3));
+    @ParameterizedTest
+    @MethodSource("conditionTypeIds")
+    void testId(LocalPartitionStateEnum conditionType, int expectedId) {
+        assertEquals(expectedId, conditionType.id());
+    }
 
-        assertEquals(LocalPartitionStateEnum.CATCHING_UP, LocalPartitionStateEnum.fromOrdinal(4));
+    /** Checks that the ID does not change, since the enum will be transferred in the {@link NetworkMessage}. */
+    @ParameterizedTest
+    @MethodSource("conditionTypeIds")
+    void testFromId(LocalPartitionStateEnum expectedEnumEntry, int id) {
+        assertEquals(expectedEnumEntry, LocalPartitionStateEnum.fromId(id));
 
-        assertEquals(LocalPartitionStateEnum.BROKEN, LocalPartitionStateEnum.fromOrdinal(5));
+    }
 
-        assertThrows(IllegalArgumentException.class, () -> LocalPartitionStateEnum.fromOrdinal(-1));
-        assertThrows(IllegalArgumentException.class, () -> LocalPartitionStateEnum.fromOrdinal(6));
+    @Test
+    void testFromIdThrows() {
+        assertThrows(IllegalArgumentException.class, () -> LocalPartitionStateEnum.fromId(-1));
+        assertThrows(IllegalArgumentException.class, () -> LocalPartitionStateEnum.fromId(6));
     }
 }
diff --git a/modules/partition-replicator/src/test/java/org/apache/ignite/internal/partition/replicator/network/replication/RequestTypeTest.java b/modules/partition-replicator/src/test/java/org/apache/ignite/internal/partition/replicator/network/replication/RequestTypeTest.java
index d1efec67f3e..5a5ec3b7f01 100644
--- a/modules/partition-replicator/src/test/java/org/apache/ignite/internal/partition/replicator/network/replication/RequestTypeTest.java
+++ b/modules/partition-replicator/src/test/java/org/apache/ignite/internal/partition/replicator/network/replication/RequestTypeTest.java
@@ -18,56 +18,107 @@
 
 package org.apache.ignite.internal.partition.replicator.network.replication;
 
+import static org.apache.ignite.internal.partition.replicator.network.replication.RequestType.RO_GET;
+import static org.apache.ignite.internal.partition.replicator.network.replication.RequestType.RO_GET_ALL;
+import static org.apache.ignite.internal.partition.replicator.network.replication.RequestType.RO_SCAN;
+import static org.apache.ignite.internal.partition.replicator.network.replication.RequestType.RW_DELETE;
+import static org.apache.ignite.internal.partition.replicator.network.replication.RequestType.RW_DELETE_ALL;
+import static org.apache.ignite.internal.partition.replicator.network.replication.RequestType.RW_DELETE_EXACT;
+import static org.apache.ignite.internal.partition.replicator.network.replication.RequestType.RW_DELETE_EXACT_ALL;
+import static org.apache.ignite.internal.partition.replicator.network.replication.RequestType.RW_GET;
+import static org.apache.ignite.internal.partition.replicator.network.replication.RequestType.RW_GET_ALL;
+import static org.apache.ignite.internal.partition.replicator.network.replication.RequestType.RW_GET_AND_DELETE;
+import static org.apache.ignite.internal.partition.replicator.network.replication.RequestType.RW_GET_AND_REPLACE;
+import static org.apache.ignite.internal.partition.replicator.network.replication.RequestType.RW_GET_AND_UPSERT;
+import static org.apache.ignite.internal.partition.replicator.network.replication.RequestType.RW_INSERT;
+import static org.apache.ignite.internal.partition.replicator.network.replication.RequestType.RW_INSERT_ALL;
+import static org.apache.ignite.internal.partition.replicator.network.replication.RequestType.RW_REPLACE;
+import static org.apache.ignite.internal.partition.replicator.network.replication.RequestType.RW_REPLACE_IF_EXIST;
+import static org.apache.ignite.internal.partition.replicator.network.replication.RequestType.RW_SCAN;
+import static org.apache.ignite.internal.partition.replicator.network.replication.RequestType.RW_UPSERT;
+import static org.apache.ignite.internal.partition.replicator.network.replication.RequestType.RW_UPSERT_ALL;
 import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.params.provider.Arguments.arguments;
 
+import java.util.EnumSet;
+import java.util.Set;
+import java.util.stream.Stream;
 import org.apache.ignite.internal.network.NetworkMessage;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.EnumSource;
+import org.junit.jupiter.params.provider.MethodSource;
 
 /** For {@link RequestType} testing. */
 public class RequestTypeTest {
-    /** Checks that the ordinal does not change, since the enum will be transferred in the {@link NetworkMessage}. */
-    @Test
-    void testFromOrdinal() {
-        assertEquals(RequestType.RW_GET, RequestType.fromOrdinal(0));
-
-        assertEquals(RequestType.RW_GET_ALL, RequestType.fromOrdinal(1));
-
-        assertEquals(RequestType.RW_DELETE, RequestType.fromOrdinal(2));
-
-        assertEquals(RequestType.RW_DELETE_ALL, RequestType.fromOrdinal(3));
-
-        assertEquals(RequestType.RW_DELETE_EXACT, RequestType.fromOrdinal(4));
-
-        assertEquals(RequestType.RW_DELETE_EXACT_ALL, RequestType.fromOrdinal(5));
-
-        assertEquals(RequestType.RW_INSERT, RequestType.fromOrdinal(6));
-
-        assertEquals(RequestType.RW_INSERT_ALL, RequestType.fromOrdinal(7));
-
-        assertEquals(RequestType.RW_UPSERT, RequestType.fromOrdinal(8));
-
-        assertEquals(RequestType.RW_UPSERT_ALL, RequestType.fromOrdinal(9));
-
-        assertEquals(RequestType.RW_REPLACE, RequestType.fromOrdinal(10));
-
-        assertEquals(RequestType.RW_REPLACE_IF_EXIST, RequestType.fromOrdinal(11));
-
-        assertEquals(RequestType.RW_GET_AND_DELETE, RequestType.fromOrdinal(12));
-
-        assertEquals(RequestType.RW_GET_AND_REPLACE, RequestType.fromOrdinal(13));
+    private static final Set<RequestType> EXPECTED_RW_READS = EnumSet.of(RW_GET, RW_GET_ALL, RW_SCAN);
+    private static final Set<RequestType> EXPECTED_NON_WRITES = EnumSet.of(RW_GET, RW_GET_ALL, RW_SCAN, RO_GET, RO_GET_ALL, RO_SCAN);
+
+    private static Stream<Arguments> requestTypeIds() {
+        return Stream.of(
+                arguments(RW_GET, 0),
+                arguments(RW_GET_ALL, 1),
+                arguments(RW_DELETE, 2),
+                arguments(RW_DELETE_ALL, 3),
+                arguments(RW_DELETE_EXACT, 4),
+                arguments(RW_DELETE_EXACT_ALL, 5),
+                arguments(RW_INSERT, 6),
+                arguments(RW_INSERT_ALL, 7),
+                arguments(RW_UPSERT, 8),
+                arguments(RW_UPSERT_ALL, 9),
+                arguments(RW_REPLACE, 10),
+                arguments(RW_REPLACE_IF_EXIST, 11),
+                arguments(RW_GET_AND_DELETE, 12),
+                arguments(RW_GET_AND_REPLACE, 13),
+                arguments(RW_GET_AND_UPSERT, 14),
+                arguments(RW_SCAN, 15),
+                arguments(RO_GET, 16),
+                arguments(RO_GET_ALL, 17),
+                arguments(RO_SCAN, 18)
+        );
+    }
 
-        assertEquals(RequestType.RW_GET_AND_UPSERT, RequestType.fromOrdinal(14));
+    @ParameterizedTest
+    @MethodSource("requestTypeIds")
+    void testId(RequestType requestType, int expectedId) {
+        assertEquals(expectedId, requestType.id());
+    }
 
-        assertEquals(RequestType.RW_SCAN, RequestType.fromOrdinal(15));
+    /** Checks that the ID does not change, since the enum will be transferred in the {@link NetworkMessage}. */
+    @ParameterizedTest
+    @MethodSource("requestTypeIds")
+    void testFromId(RequestType expectedEnumEntry, int id) {
+        assertEquals(expectedEnumEntry, RequestType.fromId(id));
 
-        assertEquals(RequestType.RO_GET, RequestType.fromOrdinal(16));
+    }
 
-        assertEquals(RequestType.RO_GET_ALL, RequestType.fromOrdinal(17));
+    @Test
+    void testFromIdThrows() {
+        assertThrows(IllegalArgumentException.class, () -> RequestType.fromId(-1));
+        assertThrows(IllegalArgumentException.class, () -> RequestType.fromId(19));
+    }
 
-        assertEquals(RequestType.RO_SCAN, RequestType.fromOrdinal(18));
+    @ParameterizedTest
+    @EnumSource(RequestType.class)
+    void isRwReadWorksAsExpected(RequestType requestType) {
+        if (EXPECTED_RW_READS.contains(requestType)) {
+            assertTrue(requestType.isRwRead(), requestType + " must be an RW read");
+        } else {
+            assertFalse(requestType.isRwRead(), requestType + " must not be an RW read");
+        }
+    }
 
-        assertThrows(IllegalArgumentException.class, () -> RequestType.fromOrdinal(-1));
-        assertThrows(IllegalArgumentException.class, () -> RequestType.fromOrdinal(19));
+    @ParameterizedTest
+    @EnumSource(RequestType.class)
+    void isWriteWorksAsExpected(RequestType requestType) {
+        if (EXPECTED_NON_WRITES.contains(requestType)) {
+            assertFalse(requestType.isWrite(), requestType + " must not be a write");
+        } else {
+            assertTrue(requestType.isWrite(), requestType + " must be a write");
+        }
     }
 }
diff --git a/modules/raft/src/main/java/org/apache/ignite/raft/jraft/entity/EnumOutter.java b/modules/raft/src/main/java/org/apache/ignite/raft/jraft/entity/EnumOutter.java
index 95eb8aa425b..77c54781117 100644
--- a/modules/raft/src/main/java/org/apache/ignite/raft/jraft/entity/EnumOutter.java
+++ b/modules/raft/src/main/java/org/apache/ignite/raft/jraft/entity/EnumOutter.java
@@ -78,17 +78,26 @@ public final class EnumOutter {
         }
 
         /**
-        * Returns the enumerated value from its ordinal.
+        * Returns the enumerated value from its id.
         *
-        * @param ordinal Ordinal of enumeration constant.
-        * @throws IllegalArgumentException If no enumeration constant by ordinal.
+        * @param id Id of enumeration constant.
+        * @throws IllegalArgumentException If no enumeration constant by id.
         */
-        public static EntryType fromOrdinal(int ordinal) throws IllegalArgumentException {
-            if (ordinal < 0 || ordinal >= VALUES.length) {
-                throw new IllegalArgumentException("No enum constant from ordinal: " + ordinal);
+        public static EntryType fromId(int id) throws IllegalArgumentException {
+            EntryType entryType = forNumber(id);
+            if (entryType == null) {
+                throw new IllegalArgumentException("No enum constant from id: " + id);
             }
+            return entryType;
+        }
 
-            return VALUES[ordinal];
+        /**
+        * Returns the id of enumeration constant, used by serialization.
+        *
+        * @return id of enumeration constant, used by serialization.
+        */
+        public int id() {
+            return getNumber();
         }
 
         private final int value;
diff --git a/modules/raft/src/test/java/org/apache/ignite/raft/jraft/entity/EntryTypeTest.java b/modules/raft/src/test/java/org/apache/ignite/raft/jraft/entity/EntryTypeTest.java
index 896760cf71a..b2a21a7bc7a 100644
--- a/modules/raft/src/test/java/org/apache/ignite/raft/jraft/entity/EntryTypeTest.java
+++ b/modules/raft/src/test/java/org/apache/ignite/raft/jraft/entity/EntryTypeTest.java
@@ -26,18 +26,18 @@ import org.junit.jupiter.api.Test;
 
 /** For {@link EntryType} testing. */
 public class EntryTypeTest {
-    /** Checks that the ordinal does not change, since the enum will be transferred in the {@link NetworkMessage}. */
+    /** Checks that the ID does not change, since the enum will be transferred in the {@link NetworkMessage}. */
     @Test
-    void testFromOrdinal() {
-        assertEquals(EntryType.ENTRY_TYPE_UNKNOWN, EntryType.fromOrdinal(0));
+    void testFromId() {
+        assertEquals(EntryType.ENTRY_TYPE_UNKNOWN, EntryType.fromId(0));
 
-        assertEquals(EntryType.ENTRY_TYPE_NO_OP, EntryType.fromOrdinal(1));
+        assertEquals(EntryType.ENTRY_TYPE_NO_OP, EntryType.fromId(1));
 
-        assertEquals(EntryType.ENTRY_TYPE_DATA, EntryType.fromOrdinal(2));
+        assertEquals(EntryType.ENTRY_TYPE_DATA, EntryType.fromId(2));
 
-        assertEquals(EntryType.ENTRY_TYPE_CONFIGURATION, EntryType.fromOrdinal(3));
+        assertEquals(EntryType.ENTRY_TYPE_CONFIGURATION, EntryType.fromId(3));
 
-        assertThrows(IllegalArgumentException.class, () -> EntryType.fromOrdinal(-1));
-        assertThrows(IllegalArgumentException.class, () -> EntryType.fromOrdinal(4));
+        assertThrows(IllegalArgumentException.class, () -> EntryType.fromId(-1));
+        assertThrows(IllegalArgumentException.class, () -> EntryType.fromId(4));
     }
 }
diff --git a/modules/table/src/test/java/org/apache/ignite/internal/table/distributed/replicator/action/RequestTypeTest.java b/modules/table/src/test/java/org/apache/ignite/internal/table/distributed/replicator/action/RequestTypeTest.java
deleted file mode 100644
index 90b56fbbf94..00000000000
--- a/modules/table/src/test/java/org/apache/ignite/internal/table/distributed/replicator/action/RequestTypeTest.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * 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.internal.table.distributed.replicator.action;
-
-
-import static org.apache.ignite.internal.partition.replicator.network.replication.RequestType.RO_GET;
-import static org.apache.ignite.internal.partition.replicator.network.replication.RequestType.RO_GET_ALL;
-import static org.apache.ignite.internal.partition.replicator.network.replication.RequestType.RO_SCAN;
-import static org.apache.ignite.internal.partition.replicator.network.replication.RequestType.RW_DELETE;
-import static org.apache.ignite.internal.partition.replicator.network.replication.RequestType.RW_DELETE_ALL;
-import static org.apache.ignite.internal.partition.replicator.network.replication.RequestType.RW_DELETE_EXACT;
-import static org.apache.ignite.internal.partition.replicator.network.replication.RequestType.RW_DELETE_EXACT_ALL;
-import static org.apache.ignite.internal.partition.replicator.network.replication.RequestType.RW_GET;
-import static org.apache.ignite.internal.partition.replicator.network.replication.RequestType.RW_GET_ALL;
-import static org.apache.ignite.internal.partition.replicator.network.replication.RequestType.RW_GET_AND_DELETE;
-import static org.apache.ignite.internal.partition.replicator.network.replication.RequestType.RW_GET_AND_REPLACE;
-import static org.apache.ignite.internal.partition.replicator.network.replication.RequestType.RW_GET_AND_UPSERT;
-import static org.apache.ignite.internal.partition.replicator.network.replication.RequestType.RW_INSERT;
-import static org.apache.ignite.internal.partition.replicator.network.replication.RequestType.RW_INSERT_ALL;
-import static org.apache.ignite.internal.partition.replicator.network.replication.RequestType.RW_REPLACE;
-import static org.apache.ignite.internal.partition.replicator.network.replication.RequestType.RW_REPLACE_IF_EXIST;
-import static org.apache.ignite.internal.partition.replicator.network.replication.RequestType.RW_SCAN;
-import static org.apache.ignite.internal.partition.replicator.network.replication.RequestType.RW_UPSERT;
-import static org.apache.ignite.internal.partition.replicator.network.replication.RequestType.RW_UPSERT_ALL;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
-import java.util.EnumSet;
-import java.util.Set;
-import org.apache.ignite.internal.network.NetworkMessage;
-import org.apache.ignite.internal.partition.replicator.network.replication.RequestType;
-import org.junit.jupiter.api.Test;
-
-class RequestTypeTest {
-    @Test
-    void isRwReadWorksAsExpected() {
-        Set<RequestType> expectedRwReads = EnumSet.of(RW_GET, RW_GET_ALL, RW_SCAN);
-
-        for (RequestType requestType : RequestType.values()) {
-            if (expectedRwReads.contains(requestType)) {
-                assertTrue(requestType.isRwRead(), requestType + " must be an RW read");
-            } else {
-                assertFalse(requestType.isRwRead(), requestType + " must not be an RW read");
-            }
-        }
-    }
-
-    @Test
-    void isWriteWorksAsExpected() {
-        Set<RequestType> expectedNonWrites = EnumSet.of(RW_GET, RW_GET_ALL, RW_SCAN, RO_GET, RO_GET_ALL, RO_SCAN);
-
-        for (RequestType requestType : RequestType.values()) {
-            if (expectedNonWrites.contains(requestType)) {
-                assertFalse(requestType.isWrite(), requestType + " must not be a write");
-            } else {
-                assertTrue(requestType.isWrite(), requestType + " must be a write");
-            }
-        }
-    }
-
-    /** Checks that the ordinal does not change, since the enum will be transferred in the {@link NetworkMessage}. */
-    @Test
-    void testFromOrdinal() {
-        assertEquals(RW_GET, RequestType.fromOrdinal(0));
-
-        assertEquals(RW_GET_ALL, RequestType.fromOrdinal(1));
-
-        assertEquals(RW_DELETE, RequestType.fromOrdinal(2));
-
-        assertEquals(RW_DELETE_ALL, RequestType.fromOrdinal(3));
-
-        assertEquals(RW_DELETE_EXACT, RequestType.fromOrdinal(4));
-
-        assertEquals(RW_DELETE_EXACT_ALL, RequestType.fromOrdinal(5));
-
-        assertEquals(RW_INSERT, RequestType.fromOrdinal(6));
-
-        assertEquals(RW_INSERT_ALL, RequestType.fromOrdinal(7));
-
-        assertEquals(RW_UPSERT, RequestType.fromOrdinal(8));
-
-        assertEquals(RW_UPSERT_ALL, RequestType.fromOrdinal(9));
-
-        assertEquals(RW_REPLACE, RequestType.fromOrdinal(10));
-
-        assertEquals(RW_REPLACE_IF_EXIST, RequestType.fromOrdinal(11));
-
-        assertEquals(RW_GET_AND_DELETE, RequestType.fromOrdinal(12));
-
-        assertEquals(RW_GET_AND_REPLACE, RequestType.fromOrdinal(13));
-
-        assertEquals(RW_GET_AND_UPSERT, RequestType.fromOrdinal(14));
-
-        assertEquals(RW_SCAN, RequestType.fromOrdinal(15));
-
-        assertEquals(RO_GET, RequestType.fromOrdinal(16));
-
-        assertEquals(RO_GET_ALL, RequestType.fromOrdinal(17));
-
-        assertEquals(RO_SCAN, RequestType.fromOrdinal(18));
-
-        assertThrows(IllegalArgumentException.class, () -> RequestType.fromOrdinal(-1));
-        assertThrows(IllegalArgumentException.class, () -> RequestType.fromOrdinal(19));
-    }
-}
diff --git a/modules/transactions/src/main/java/org/apache/ignite/internal/tx/TxMetaSerializer.java b/modules/transactions/src/main/java/org/apache/ignite/internal/tx/TxMetaSerializer.java
index dc521bada31..2663acbd278 100644
--- a/modules/transactions/src/main/java/org/apache/ignite/internal/tx/TxMetaSerializer.java
+++ b/modules/transactions/src/main/java/org/apache/ignite/internal/tx/TxMetaSerializer.java
@@ -52,7 +52,7 @@ public class TxMetaSerializer extends VersionedSerializer<TxMeta> {
 
         out.writeBoolean(hasAnyZonePartitionIds);
 
-        out.writeVarInt(meta.txState().ordinal());
+        out.writeVarInt(meta.txState().id());
 
         out.writeVarInt(meta.enlistedPartitions().size());
         for (EnlistedPartitionGroup enlistedPartitionGroup : meta.enlistedPartitions()) {
@@ -85,7 +85,7 @@ public class TxMetaSerializer extends VersionedSerializer<TxMeta> {
             usesZonePartitionIds = false;
         }
 
-        TxState state = TxState.fromOrdinal(in.readVarIntAsInt());
+        TxState state = TxState.fromId(in.readVarIntAsInt());
         List<EnlistedPartitionGroup> enlistedPartitions = readEnlistedPartitions(in, protoVer, usesZonePartitionIds);
         HybridTimestamp commitTimestamp = HybridTimestamp.readNullableFrom(in);
 
diff --git a/modules/transactions/src/main/java/org/apache/ignite/internal/tx/TxState.java b/modules/transactions/src/main/java/org/apache/ignite/internal/tx/TxState.java
index c4128b71892..49dcfff8ca1 100644
--- a/modules/transactions/src/main/java/org/apache/ignite/internal/tx/TxState.java
+++ b/modules/transactions/src/main/java/org/apache/ignite/internal/tx/TxState.java
@@ -28,7 +28,7 @@ public enum TxState {
     /**
      * Active transaction that is in progress.
      */
-    PENDING,
+    PENDING(0),
 
     /**
      * Transaction can be put in this state on a transaction coordinator or a commit partition on a start of finalization process
@@ -37,23 +37,23 @@ public enum TxState {
      * commit partition on a coordinator, or finishes the transaction recovery on a commit partition. This state can be also seen locally
      * on data nodes if they are colocated with the coordinator or the commit partition.
      */
-    FINISHING,
+    FINISHING(1),
 
     /**
      * Aborted (rolled back) transaction.
      */
-    ABORTED,
+    ABORTED(2),
 
     /**
      * Committed transaction.
      */
-    COMMITTED,
+    COMMITTED(3),
 
     /**
      * State that is assigned to a transaction due to absence of coordinator. It is temporary and can be changed to
      * {@link TxState#COMMITTED} or {@link TxState#ABORTED} after recovery or successful write intent resolution.
      */
-    ABANDONED;
+    ABANDONED(4);
 
     private static final boolean[][] TRANSITION_MATRIX = {
             { false, true,  true, true,  true,  true },
@@ -64,9 +64,6 @@ public enum TxState {
             { false,  false,  true,  true,  true,  true }
     };
 
-    /** Cached array with all enum values. */
-    private static final TxState[] VALUES = values();
-
     /**
      * Checks whether the state is final, i.e. no transition from this state is allowed.
      *
@@ -93,17 +90,32 @@ public enum TxState {
         return TRANSITION_MATRIX[beforeOrd][afterOrd];
     }
 
+
+    private final int id;
+
+    TxState(int id) {
+        this.id = id;
+    }
+
     /**
-     * Returns the enumerated value from its ordinal.
+     * Returns the enumerated value from its id.
      *
-     * @param ordinal Ordinal of enumeration constant.
-     * @throws IllegalArgumentException If no enumeration constant by ordinal.
+     * @param id Id of enumeration constant.
+     * @throws IllegalArgumentException If no enumeration constant by id.
      */
-    public static TxState fromOrdinal(int ordinal) throws IllegalArgumentException {
-        if (ordinal < 0 || ordinal >= VALUES.length) {
-            throw new IllegalArgumentException("No enum constant from ordinal: " + ordinal);
+    public static TxState fromId(int id) throws IllegalArgumentException {
+        switch (id) {
+            case 0: return PENDING;
+            case 1: return FINISHING;
+            case 2: return ABORTED;
+            case 3: return COMMITTED;
+            case 4: return ABANDONED;
+            default:
+                throw new IllegalArgumentException("No enum constant from id: " + id);
         }
+    }
 
-        return VALUES[ordinal];
+    public int id() {
+        return id;
     }
 }
diff --git a/modules/transactions/src/test/java/org/apache/ignite/internal/tx/TxStateTest.java b/modules/transactions/src/test/java/org/apache/ignite/internal/tx/TxStateTest.java
index 3be37658d3b..4fdb0b44abd 100644
--- a/modules/transactions/src/test/java/org/apache/ignite/internal/tx/TxStateTest.java
+++ b/modules/transactions/src/test/java/org/apache/ignite/internal/tx/TxStateTest.java
@@ -23,9 +23,14 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertThrows;
 import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.params.provider.Arguments.arguments;
 
+import java.util.stream.Stream;
 import org.apache.ignite.internal.network.NetworkMessage;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
 
 /** For {@link TxState} testing. */
 public class TxStateTest {
@@ -123,20 +128,35 @@ public class TxStateTest {
         assertTrue(TxState.checkTransitionCorrectness(TxState.ABANDONED, TxState.ABANDONED));
     }
 
-    /** Checks that the ordinal does not change, since the enum will be transferred in the {@link NetworkMessage}. */
-    @Test
-    void testFromOrdinal() {
-        assertEquals(TxState.PENDING, TxState.fromOrdinal(0));
 
-        assertEquals(TxState.FINISHING, TxState.fromOrdinal(1));
+    private static Stream<Arguments> txStateIds() {
+        return Stream.of(
+                arguments(TxState.PENDING, 0),
+                arguments(TxState.FINISHING, 1),
+                arguments(TxState.ABORTED, 2),
+                arguments(TxState.COMMITTED, 3),
+                arguments(TxState.ABANDONED, 4)
+        );
+    }
+
 
-        assertEquals(TxState.ABORTED, TxState.fromOrdinal(2));
+    @ParameterizedTest
+    @MethodSource("txStateIds")
+    void testId(TxState txState, int expectedId) {
+        assertEquals(expectedId, txState.id());
+    }
 
-        assertEquals(TxState.COMMITTED, TxState.fromOrdinal(3));
+    /** Checks that the ID does not change, since the enum will be transferred in the {@link NetworkMessage}. */
+    @ParameterizedTest
+    @MethodSource("txStateIds")
+    void testFromId(TxState expectedEnumEntry, int id) {
+        assertEquals(expectedEnumEntry, TxState.fromId(id));
 
-        assertEquals(TxState.ABANDONED, TxState.fromOrdinal(4));
+    }
 
-        assertThrows(IllegalArgumentException.class, () -> TxState.fromOrdinal(-1));
-        assertThrows(IllegalArgumentException.class, () -> TxState.fromOrdinal(5));
+    @Test
+    void testFromIdThrows() {
+        assertThrows(IllegalArgumentException.class, () -> TxState.fromId(-1));
+        assertThrows(IllegalArgumentException.class, () -> TxState.fromId(5));
     }
 }