diff --git a/core/modules/workspaces/src/EntityOperations.php b/core/modules/workspaces/src/EntityOperations.php
index 118c68bd895e66863bb8adec040b2f81e951003d..b46929b3d025e9e9a256f67a1998ae8fda817c26 100644
--- a/core/modules/workspaces/src/EntityOperations.php
+++ b/core/modules/workspaces/src/EntityOperations.php
@@ -147,6 +147,16 @@ public function entityPresave(EntityInterface $entity) {
       $entity->isDefaultRevision(FALSE);
     }
 
+    // In ::entityFormEntityBuild() we mark the entity as a non-default revision
+    // so that validation constraints can rely on $entity->isDefaultRevision()
+    // always returning FALSE when an entity form is submitted in a workspace.
+    // However, after validation has run, we need to revert that flag so the
+    // first revision of a new entity is correctly seen by the system as the
+    // default revision.
+    if ($entity->isNew()) {
+      $entity->isDefaultRevision(TRUE);
+    }
+
     // Track the workspaces in which the new revision was saved.
     if (!$entity->isSyncing()) {
       $field_name = $entity->getEntityType()->getRevisionMetadataKey('workspace');
@@ -326,6 +336,10 @@ public function entityFormAlter(array &$form, FormStateInterface $form_state, $f
    * Entity builder that marks all supported entities as pending revisions.
    */
   public static function entityFormEntityBuild($entity_type_id, RevisionableInterface $entity, &$form, FormStateInterface &$form_state) {
+    // Ensure that all entity forms are signaling that a new revision will be
+    // created.
+    $entity->setNewRevision(TRUE);
+
     // Set the non-default revision flag so that validation constraints are also
     // aware that a pending revision is about to be created.
     $entity->isDefaultRevision(FALSE);
diff --git a/core/modules/workspaces/tests/src/Functional/WorkspaceMenuLinkContentIntegrationTest.php b/core/modules/workspaces/tests/src/Functional/WorkspaceMenuLinkContentIntegrationTest.php
index 7c8451730652d7c9dbe48cb42db170d32cb96b75..8df9d5632e574bf4b93a923d2bdb5c599fb826a4 100644
--- a/core/modules/workspaces/tests/src/Functional/WorkspaceMenuLinkContentIntegrationTest.php
+++ b/core/modules/workspaces/tests/src/Functional/WorkspaceMenuLinkContentIntegrationTest.php
@@ -4,7 +4,6 @@
 
 namespace Drupal\Tests\workspaces\Functional;
 
-use Drupal\menu_link_content\Entity\MenuLinkContent;
 use Drupal\Tests\BrowserTestBase;
 use Drupal\workspaces\Entity\Workspace;
 
@@ -31,6 +30,7 @@ class WorkspaceMenuLinkContentIntegrationTest extends BrowserTestBase {
   protected static $modules = [
     'block',
     'menu_link_content',
+    'menu_ui',
     'node',
     'workspaces',
   ];
@@ -48,6 +48,7 @@ protected function setUp(): void {
 
     $permissions = [
       'access administration pages',
+      'administer menu',
       'administer site configuration',
       'administer workspaces',
     ];
@@ -65,19 +66,29 @@ public function testWorkspacesWithCustomMenuLinks() {
 
     $default_title = 'default';
     $default_link = '#live';
-    $menu_link_content = MenuLinkContent::create([
-      'title' => $default_title,
-      'menu_name' => 'main',
-      'link' => [['uri' => 'internal:/' . $default_link]],
-    ]);
-    $menu_link_content->save();
+
+    // Add a new menu link in Live.
+    $this->drupalGet('admin/structure/menu/manage/main/add');
+    $this->submitForm([
+      'title[0][value]' => $default_title,
+      'link[0][uri]' => $default_link,
+    ], 'Save');
+    $menu_links = \Drupal::entityTypeManager()
+      ->getStorage('menu_link_content')
+      ->loadByProperties(['title' => $default_title]);
+    $menu_link = reset($menu_links);
 
     $pending_title = 'pending';
     $pending_link = 'http://example.com';
+
+    // Change the menu link in 'stage' and check that the updated values are
+    // visible in that workspace.
     $this->switchToWorkspace($stage);
-    $menu_link_content->set('title', $pending_title);
-    $menu_link_content->set('link', [['uri' => $pending_link]]);
-    $menu_link_content->save();
+    $this->drupalGet("admin/structure/menu/item/{$menu_link->id()}/edit");
+    $this->submitForm([
+      'title[0][value]' => $pending_title,
+      'link[0][uri]' => $pending_link,
+    ], 'Save');
 
     $this->drupalGet('');
     $assert_session = $this->assertSession();
@@ -85,12 +96,11 @@ public function testWorkspacesWithCustomMenuLinks() {
     $assert_session->linkByHrefExists($pending_link);
 
     // Add a new menu link in the Stage workspace.
-    $menu_link_content = MenuLinkContent::create([
-      'title' => 'stage link',
-      'menu_name' => 'main',
-      'link' => [['uri' => 'internal:/#stage']],
-    ]);
-    $menu_link_content->save();
+    $this->drupalGet('admin/structure/menu/manage/main/add');
+    $this->submitForm([
+      'title[0][value]' => 'stage link',
+      'link[0][uri]' => '#stage',
+    ], 'Save');
 
     $this->drupalGet('');
     $assert_session->linkExists('stage link');
diff --git a/core/modules/workspaces/workspaces.module b/core/modules/workspaces/workspaces.module
index 09c91af77ad1f74a32bb69b457c18be3e1a21775..cc8cf8e1dabdf76000f7b4a3b7887a77c633e8f3 100644
--- a/core/modules/workspaces/workspaces.module
+++ b/core/modules/workspaces/workspaces.module
@@ -39,11 +39,19 @@ function workspaces_help($route_name, RouteMatchInterface $route_match) {
  * Implements hook_module_implements_alter().
  */
 function workspaces_module_implements_alter(&$implementations, $hook): void {
+  // Move our 'hook_entity_presave' implementation at the beginning to ensure
+  // that other presave implementations are aware of the changes done in
+  // \Drupal\workspaces\EntityOperations::entityPresave().
+  if ($hook === 'entity_presave') {
+    $implementation = $implementations['workspaces'];
+    $implementations = ['workspaces' => $implementation] + $implementations;
+  }
+
+  // Move our 'hook_entity_insert' implementation at the end to ensure that
+  // the second (pending) revision created for published entities is not used
+  // by other 'hook_entity_insert' implementations.
+  // @see \Drupal\workspaces\EntityOperations::entityInsert()
   if ($hook === 'entity_insert') {
-    // Move our 'hook_entity_insert' implementation at the end to ensure that
-    // the second (pending) revision created for published entities is not used
-    // by other 'hook_entity_insert' implementations.
-    // @see \Drupal\workspaces\EntityOperations::entityInsert()
     $group = $implementations['workspaces'];
     unset($implementations['workspaces']);
     $implementations['workspaces'] = $group;